fix: make check-flake-file cacheable across unrelated commits - #138
Merged
Merged
Conversation
check-flake-file interpolated the whole of `self`, so its derivation hash changed on every commit. A never-seen hash cannot be substituted, so CI had to rebuild it each time, and fetch its build inputs again. The check and its hooks now see a copy of the flake root that holds only `flake-file.check-files` (default: flake.nix and flake.lock). It is also built with runCommand + preferLocalBuild instead of runCommandLocal, so the now-stable output can be substituted from a binary cache. Closes #137
The hooks guide and options reference described an `exec` string that the hook submodule never had. Hooks take `program`, a function from pkgs to a derivation with meta.mainProgram. Write hooks run it from the flake root; check hooks receive the flake root path as their first argument.
drupol
added a commit
to drupol/nixpkgs
that referenced
this pull request
Sep 27, 2026
drupol
added a commit
to drupol/nixpkgs
that referenced
this pull request
Sep 27, 2026
drupol
added a commit
to drupol/nixpkgs
that referenced
this pull request
Sep 27, 2026
drupol
added a commit
to drupol/nixpkgs
that referenced
this pull request
Sep 27, 2026
drupol
added a commit
to drupol/nixpkgs
that referenced
this pull request
Sep 27, 2026
drupol
added a commit
to drupol/nixpkgs
that referenced
this pull request
Sep 27, 2026
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.
Summary
Closes #137.
check-flake-fileinterpolated the whole ofself(diff -u ${top.inputs.self}/flake.nix …), so its derivation hash changed on every commit, including ones that only touch a README. A derivation whose hash has never been seen cannot be substituted from any cache, so CI rebuilds it every time and has to fetch its build inputs again (bash, stdenv, diffutils,flake-formatted,nix-auto-follow, …: 75 paths indev/). The check's output is an empty file with no references, so a cache filled from outputs never holds those inputs. That is the repeated download reported in #137.This is also why swapping
runCommandLocalforrunCommandalone made no difference: the hash was still new on each commit.Changes:
check-hooksnow receive a copy of the flake root containing only the files in the new optionflake-file.check-files(default[ "flake.nix" "flake.lock" ]). Commits that change other files leave the check's hash unchanged.runCommandLocal→runCommandwithpreferLocalBuild = true. It still builds locally rather than asking remote builders (the intent of feat: preferLocalBuild #110), but withallowSubstitutesleft at its default, the now-stable output can come from a binary cache.execstring field that hooks never had. They now documentprogram, with examples checked against the dev flake.Behaviour change for custom check-hooks: hooks used to receive the full flake source. A hook that reads other files must now list them in
flake-file.check-files. If it doesn't, it fails with a missing file rather than passing silently.treefmt-checkhas the same shape but formats the whole tree, so it will always depend on every file. flake-file can't fix it. Caching it needs the check's build-time closure to be kept in the CI cache.Validation
Measured on the
dev/flake with Nix 2.34.8:README.mdcheck-flake-file.drvhash changesflake.nixgen/x.txtviacheck-filescd dev && nix flake checkpasses on a clean checkout of the branch.nix-shell ./dev/bootstrap-tests.nix --run test-allpasses.