feat(ci): keep only what cache.nixos.org lacks in the Actions cache - #13
Merged
Merged
Conversation
The cache entry becomes a Nix binary cache on disk (narinfo files and zstd-compressed NARs) that the checks read as a trusted substituter, instead of an archive of the whole rooted store. After the checks, the run copies the closure of its outputs into it, asks cache.nixos.org which of those paths it serves, records the rest as this build's root, and prunes the cache to the union of the surviving roots' lists before the save. Sizes for the 10 GB budget come from the narinfo FileSize fields, so they are the compressed sizes GitHub counts rather than the uncompressed closure sizes used before. Keys move from the nix- prefix to cache- so that no entry of the earlier form is restored; the earlier entries expire unused. The push to the clhodapp cache covers this run's outputs; earlier runs pushed theirs. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…info `nix path-info --store <cache>` realises its arguments against that store with the configured substituters before answering, and fails on a path no substituter has, which every locally built check output is. The probe is now a HEAD request per path for the cache's narinfo file, which is the question being asked. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Both awk joins used the NR == FNR idiom, which takes the second file for the first when the first is empty: a closure with no upstream-served path was recorded as fully served and the entry saved with nothing in it. The joins now test FILENAME against ARGV[1]. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The Actions cache entry this pipeline keeps between runs held the whole rooted Nix store: everything the checks' closures reach, including the paths cache.nixos.org serves (glibc, gcc, the language runtimes), which every run could fetch from there instead. This changes what the entry holds so that those paths stay out of it.
How it works now
/home/runner/ci-cache: narinfo files and zstd-compressed NARs) plus the root tree underroots/. Nix reads it as a substituter, listed in nix.conf asfile:///home/runner/ci-cache?trusted=true; thetrustedstore parameter accepts that store's unsigned paths and no other's.nix flake check, the run copies the closure of the flake's checks and packages into the binary cache, asks cache.nixos.org which of those paths it serves (a HEAD request per path for its narinfo file, 32 in parallel; a failed request counts as not served, which only keeps more), and records the rest as this build's root (roots/<class>/<id>/paths). The whole closure has to go in first, because a binary cache refuses a path whose references it does not hold; the served paths are deleted again before the save, and compressing them with zstd costs seconds.FileSizefields, the compressed sizes GitHub counts, instead of uncompressed closure sizes.actions/cache/restoreandactions/cache/save(v4.3.0) directly.cache-nix-actionand its store garbage collection are gone, and the root step needs no sudo.Transition
Keys move from
nix-Linux-<sha>tocache-Linux-<sha>, so no run restores an entry of the earlier form (a store archive, which the new restore step would extract before Nix is installed). The first run on main after this lands is cold and saves the first new entry; the earlier entries expire unused within GitHub's seven-day window. This pull request changes.github/, socheck-prbuilds it under the request's own scope, which is the first exercise of the new pipeline.cachix
The push to the clhodapp cache now covers the closure of this run's outputs; earlier runs pushed theirs when they were built, and
cachix pushstill skips what the cache holds. Before, each run re-pushed the closure of every kept root.Verified locally
actionlint and the repository formatter are clean. The copy, upstream probe, budget, root dropping and pruning logic was exercised with two synthetic roots and a budget that fits only one; a fresh chroot store then substituted the kept path from the file cache and its references from cache.nixos.org. Without the
trustedparameter Nix refuses the unsigned path, as intended. The first push of this branch probed upstream throughnix path-info --store, which realises its arguments before answering and failed on locally built outputs in the check-pr run; the second commit replaces it with the narinfo requests.🤖 Generated with Claude Code
Result on this branch
The check-pr run on the final commit saw 15 paths in the closure, none served by cache.nixos.org (the drivers, menus and check outputs are all built here), and kept all 15; the saved entry is 188 KB, against 102 MB for the whole-store entry main holds today. The third commit fixes an awk join that recorded every path as served when the upstream cache served none of them, which this repository hit.