ci: pin nixpkgs to flake.lock and add a nixpkgs bump bot#129
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: f5ce7e12bb
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| nixpkgs=$(nix eval --impure --raw \ | ||
| --expr '(builtins.getFlake (toString ./.)).inputs.nixpkgs.outPath') |
There was a problem hiding this comment.
Pin package updates to the same nixpkgs lock
When Build starts resolving <nixpkgs> from flake.lock here, the scheduled package updater in .github/workflows/update.yml still installs nixpkgs=channel:nixos-unstable for both package detection and nix-update. While the channel is ahead of the lock (the normal state until the new nixpkgs PR is merged), package bump PRs are generated/evaluated against a different nixpkgs than the required Build workflow uses, so bot PRs can fail CI or reintroduce the same scheduled toolchain drift this change is trying to avoid. Pin the package update jobs to the locked nixpkgs as well, or explicitly update/build them through the nixpkgs bump branch.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Good catch — fixed in 882b8ee. detect-packages and update now pin NIX_PATH to the flake.lock nixpkgs via the same getFlake step as build.yml, so nix-update generates and verifies bumps against the exact nixpkgs the required Build check uses (no channel drift, no FOD-hash mismatch). update-nixpkgs stays unpinned since its job is to move the pin.
Build read nixpkgs from a live `channel:nixos-unstable`, decoupled from the repo's own flake.lock pin. The toolchain drifted underneath CI between runs, so a breaking bump (rustc 1.96 turning ethnum's transmute into E0512) landed on a scheduled run instead of on a PR. - build.yml: derive NIX_PATH from the flake's locked nixpkgs via getFlake and drop the channel matrix, so CI builds the exact nixpkgs in flake.lock — the same one `nix build .#<pkg>` uses. - update.yml: add an `update-nixpkgs` job that runs `nix flake update nixpkgs` on the daily cadence and opens an `auto-update/nixpkgs` PR. Build runs on that branch against the new pin, so a toolchain break surfaces on the bump PR before merge rather than on a later scheduled run.
f5ce7e1 to
68dde27
Compare
The Build check builds against the flake.lock pin, but update.yml's detect-packages and update jobs still used nixpkgs=channel:nixos-unstable. nix-update then computed hashes and built bumps against a different nixpkgs than the gating Build, so a bump could pass here yet fail the required check (or commit an FOD hash Build rejects). Pin both jobs to the flake.lock nixpkgs via the same getFlake NIX_PATH step used in build.yml. update-nixpkgs stays unpinned since its job is to move the pin.
Why
CI built against a live channel (
nixpkgs=channel:nixos-unstable), decoupled fromflake.lock. That channel drifts underneath CI between runs, so a toolchain bump (rustc, Python) breaks unrelated packages on a scheduled run instead of on the PR that caused it. This is exactly how the rsql/rustc-1.96 break (#128) slipped through, and how mlx-bin's cp314 assert stayed green whileflake.lockstill shipped Python 3.13.What
build.yml: pinNIX_PATHto theflake.locknixpkgs viabuiltins.getFlake, and drop the live-channel matrix. CI is now pure — it builds the exact nixpkgs the repo commits.update.yml: add anupdate-nixpkgsjob (same daily cadence) that runsnix flake update nixpkgsand opens anauto-update/nixpkgsPR. nixpkgs now moves only through a reviewable PR, and that PR is built against the new pin — so toolchain breakage surfaces before merge. Also pin thedetect-packagesandupdatejobs toflake.lock(droppingnixpkgs=channel:nixos-unstable), sonix-updategenerates and verifies bumps against the same nixpkgs the Build check uses — not a drifting channel.update-nixpkgsstays unpinned; its job is to move the pin.flake.lock: initial bumpa799d3e3886d → e2587caef70c(2026-06-06 → 2026-07-23) to make the pin current. This brings defaultpython33.13 → 3.14 (satisfies mlx-bin's cp314 assert) and rustc 1.95 → 1.97 (needs the ethnum patch from fix(rsql): patch vendored ethnum 1.5.2 -> 1.5.3 for rustc 1.96 #128).Dependency
Requires #128 (rsql ethnum patch), now merged — without it, the rustc-1.97 pin fails to compile rsql. This branch is rebased on top of that merge.
Effect
From here on, every nixpkgs/toolchain move lands as an
auto-update/nixpkgsPR that is built against the new pin before merge — no more silent drift breaking scheduled builds.