Changelog

The suite timing page now leads with the suite's total duration, set large at the top. Each phase row took on its phase's colour, so a row and its bars in the timeline read as the same thing, and the timeline gained a legend for every colour and hatch it draws. Hovering or tabbing to a bar, a table row or a legend entry now lights every part of the page that shows the same thing. The duration columns are right-aligned behind an icon each, and the timeline's own colours follow the dark theme instead of staying tuned for a white page.

A worker with no work left that it may take now frees itself within two minutes, instead of waiting for its owner's queue to empty. Other owners' jobs used to wait for a machine that was never going to come free.

The number of postgres connections per pool is now 16 by default.

26-09.10

Admin

A leader can now be configured to build only some branches on a push, rather than only whether to build pushes at all. Set the push suite trigger of a forge to the branches to run-on and the ones to do-not-run-on.

The branches a test or a deployment runs on can now be named with a glob pattern. release/* matches one segment of a branch name, release/** matches any number of them, and ? matches a single character.

26-09.8

Admin

The leader now refuses to start when its JWK file or its session key file does not hold a key.

Test and deploy jobs now run with the CI environment variable set to true.

A cache download that does not finish now reads as failed in the build log, instead of as a completed download of the full size.

26-09.5

Admin

The leader now serves correctly when its read-only connection is pointed at a read replica. A token was rejected on the very request it was generated for, logging in straight after registering could fail, pages answered 404 for rows that existed, and a run status could go never announced to GitHub, GitLab or Codeberg because the job that announces it gave up rather than retrying. Signing in through GitLab or Codeberg could be turned away as a forged request, and linking a GitLab account already held by another account could merge the two when the leader meant to refuse. A read whose answer decides what gets written now goes to the primary, and a lookup that would turn an empty answer into a 404 is confirmed against the primary before it is believed.

26-09.4

Admin

The cache now serves correctly when its read-only connection is pointed at a read replica. Finishing an upload answered 404 while the replica was catching up, the collectors skipped everything the replica had not caught up with, and a store path fetched from an upstream cache could replace a locally held one with a redirect. A read whose answer decides what gets written now goes to the primary, and a miss on the replica is confirmed against the primary before it is believed.

Tests and deployments can now say which branches they do not run on.

branches = {
  run-on = ":any";
  do-not-run-on = ":default";
};

The cache no longer drops a store path when another path with identical contents is uploaded.

Thanks to Lucien Huber of alphaloop!

Streaming a run's logs no longer hangs when the run has no output yet.

A run that NixCI cancels is now reported to GitHub, GitLab and Codeberg as cancelled, instead of being left saying it is still running.

Waiting for a build now answers 402 instead of 408 when builds are not running for the repository.

NixCI now clones private repositories with the ssh key in a secret always called GIT_SSH_KEY. The git-ssh-key configuration option is gone.

The name is fixed because reading your configuration is the first thing a build does, and it has to clone the repository to do that, so a key named only in the configuration could never authenticate the clone that reads it. If you named a secret there, rename it to GIT_SSH_KEY; the configuration option itself needs no replacement, and a leftover git-ssh-key in your configuration is reported as an unrecognised option rather than failing the build.

There is now an API reference, generated from an OpenAPI document that you can point your own tooling at. It also shows how to start a build from a shell and wait for it to finish, which fails if the build does.

26-08.2

Admin

Workers can now build with Determinate Nix.

Code blocks in the documentation are now syntax highlighted, in the same colours as the build logs. Asking a page for text/markdown gets fenced blocks that name their language.

Evaluation, build, test, and deploy jobs now fetch only the commit they are building or running, not every commit it descends from. For a repository with a long history that is much less to download, and the fetch is the first thing every job does.

A new shallow-clone option in nix-ci.nix controls it. Set shallow-clone = false for a flake that reads self.revCount, which has no history to count when only one commit is fetched.

A test or deploy job that runs in-repo still fetches the whole history, because it clones the repository and a clone has no depth control.

A build that did not have to run now says it was already built, instead of showing zero seconds as though it had. It keeps the green check of a passing build but trades the elapsed time for a lightning bolt , because the result came back instantly from the cache.

Sped up configuration jobs by only fetching the configuration file instead of the entire repository using a specialised new tool: nix-ci-config.

Builds are now skipped when the same derivation has already been built, even after the evaluation job has completed. This should speed builds up even more under heavy load.

Evaluation jobs got about 30% faster thanks to a new tool: nix-ci-eval.

As part of this change, builds that are already known to be cached will now be skipped entirely. This brings the total worker time of the common case suite down by even more than 30%.

NixCI got a changelog, and this is its first entry.

Every change to NixCI gets an entry here from now on, so you can see what shipped without having to ask. Each entry is named for its version, like 26-07.1: a two-digit year, a month, and a counter that starts again each month.