-
List packages for the current system:
nix flake show --json 2>/dev/null | \
jq -r '.inventory.packages.output.children["aarch64-darwin"].children | keys[]'
(swap aarch64-darwin for the relevant system)
-
Run nix-update per package, non-interactively, logging output:
<list-of-packages> | xargs -n1 nix-update --commit --flake 2>&1 | tee /tmp/nix-update-log.txt
This auto-commits via jj/git as it goes — expect it to create messy
working-copy commits you'll clean up in step 4. Some packages will error
out (unstable/prerelease versions, hash mismatches from tag renames,
flake-eval quirks) — note them, don't stop the batch.
-
Triage failures from the log:
"Found an unstable version ... ignored" → rerun that package alone with
nix-update --commit --flake --version=unstable <pkg>.
- Hash mismatch after a
rev change → check if upstream tags have a v
prefix (rev = version; vs rev = "v${version}";), fix, then re-run
nix-update or manually recompute via lib.fakeSha256 swap +
nix-build.
- Go
vendorHash / Rust cargoHash mismatches after any src change →
always need to be recomputed; let the build error tell you the correct
hash and paste it in.
- Rust packages with a vendored
Cargo.lock that's gitignored upstream
(check pkgs/<pkg>/Cargo.lock existing in this repo) → regenerate with
cargo generate-lockfile against a fresh clone of the new tag, copy it
over pkgs/<pkg>/Cargo.lock.
- Git dependencies in
Cargo.lock (source = "git+https://...") need
explicit hashes in cargoLock.outputHashes — get them via
nix run nixpkgs#nix-prefetch-git -- --url <url> --rev <rev> --quiet.
-
Verify each version/rev bump is actually forward, before doing any jj
cleanup. For every package where version or rev changed, run the
ancestry/date check from the "Never regress a version" rule above. Do
this for every single change — including ones nix-update picked
automatically — not just the ones that look suspicious. If a package
fails the check, revert its change (jj restore or drop that package's
commit) and investigate upstream manually before retrying.
-
Split/clean up commits with jj:
jj log -n 10
jj diff --git -r <rev> --stat
For any commit that has more than one package's files:
jj new <good-parent> -m "<pkg>: <desc>" --no-edit
jj squash --from <messy-rev> --into <new-rev> -- pkgs/<pkg>/default.nix [pkgs/<pkg>/Cargo.lock ...]
jj rebase -r <messy-rev-descendant-chain> -d <new-rev>
Abandon any leftover empty commits (jj abandon <rev>) and fix descriptions
with jj describe <rev> -m "...".
-
Verify every touched package builds:
nix-build -A <pkg1> -A <pkg2> ...
If a Rust package needs a newer rustc than the local <nixpkgs> channel
provides (see Known Issues), fall back to nix build .#<pkg> and run the
resulting binary's --version to sanity check.
-
Final check: jj log -n <N> should show one commit per changed
package, each with a description in <pkg>: <old> -> <new> format (or a
short description for non-version changes), and jj status should be
clean except for the working-copy tip.