Changelog

A banner now names GitHub, GitLab or Codeberg while calls to it are failing, so a run that will not start is one fewer thing to debug.

26-10.28

Admin

A cache garbage collection pass that raced an upload re-using a chunk it was deleting now carries on instead of stopping early.

The suite and run pages now show timestamps too instead of only durations.

A merge queue now gets a NixCI check on the commit it is waiting for.

A commit status on GitLab now waits out rate limiting instead of being dropped, and every GitLab API call costs one fewer request.

A pull request now shows one check rather than two fighting over the same name.

NixCI now waits 15 minutes rather than 80 seconds for a pull request's merge, and says so on the pull request when it gives up.

A pull request is now built against the merge it actually has.

Suites on a branch that other pull requests are based on are now cancelled when that branch is superseded or deleted.

Deleting a branch now cancels the suites still queued or running on it.

A pull request whose base branch changes is now built again against its new base.

26-10.18

Admin

A leader can now set a default configuration for all suites.

A secret masked with ::add-mask:: is now redacted even when it holds a byte that is not valid UTF-8.

26-10.16

Admin

A leader that reports its usage now serves an /admin/license page for admins to see what is being reported.

Sped up telling a worker that there is no work.

A long build or a large upload no longer loses its run partway through.
This would happen (very rarely) when a job produced no output.

An idle worker now starts a build as soon as the build it depends on finishes, instead of when it next asks for work.

26-10.12

Admin

GitHub calls are now paced at what GitHub says each App installation is allowed, instead of at one configured number for all of them.
requests-per-hour is now only the rate the first call to an installation is paced at.

A suite's GitHub commit status is now posted only when it has actually changed, so a busy repository no longer spends its installation's requests saying the same thing.

26-10.10

Admin

A leader can now accept API, cache and web requests authenticated by a token from an OIDC issuer it is configured to trust, so a workload that already holds one needs no NixCI credential of its own.
Configure the issuers under oidc, where a rule either names the NixCI user a token acts as or grants it repositories of its own.

Handing a job to a worker is now faster, so a queue of waiting runs drains sooner.

A suite now shows up on GitHub as one check called NixCI, instead of one check per run.
A branch protection rule that requires a check from NixCI should now require NixCI, because no new suite reports the per-run ones.

26-10.7

Admin

The leader and the cache now report a circuit_breaker_closed gauge for each upstream they guard.

A suite built for a pull or merge request now links straight back to it.

26-10.5

Admin

The admin panel now shows when the leader version is behind on the latest release.

A run's logs now stream in full right after it finishes, where the last of them could come back empty before.

A page whose read the database replica cancelled now loads instead of answering 500.

A browser holding a session that no longer has a user behind it is now logged out and sent to the login page.

26-10.1

Admin

The leader and the cache now report a fingerprint of the settings they are running with, as nix_ci_leader_settings_hash and nix_ci_cache_settings_hash.

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.