Capture the periodic upgrade of the four nixpkgs channels and home-manager as a repo doc: check for a NixOS stable bump first, rebase the devplayer0 fork against upstream (re-verifying the patch stack against freshly fetched refs), run the update commands, sweep version-gated TODOs, and review the remaining flake inputs. Keep the canonical, agent-agnostic procedure in docs/ and point both AGENTS.md and a thin Claude Code skill at it. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
6.7 KiB
Upgrading nixpkgs
Procedure for the periodic upgrade of all four nixpkgs channels (unstable, stable, mine,
mine-stable) and home-manager. Written to be followed by a person or any coding agent; a
Claude Code entry point exists at .claude/skills/upgrade-nixpkgs/ but the steps below are the
canonical source.
The upgrade is guided, not automated: do the mechanical and investigative steps, but stop at
the judgment points (marked ⏸) — pushing the fork, resolving rebase conflicts, editing the
flake.nix stable pins, and deleting version guards. Report findings and let the maintainer
decide. Keep a running summary and present it before any push or commit.
Work the phases in order; skip one only if explicitly scoped to a subset.
Setup facts
- Fork checkout:
~/documents/projects/nixpkgs— remotesorigin(devplayer0/nixpkgs) andupstream(NixOS/nixpkgs). Confirm the path exists; if not, ask. - Fork branches:
devplayer0(tracksnixos-unstable) anddevplayer0-stable(tracks the current NixOS stable). Each is a small stack of local patches rebased onto upstream. - Flake pins in
flake.nix(inputs):nixpkgs-unstable.url = "nixpkgs/nixos-unstable"nixpkgs-stable.url = "nixpkgs/nixos-<STABLE>"(e.g.nixos-26.05)nixpkgs-mine.url = "github:devplayer0/nixpkgs/devplayer0"nixpkgs-mine-stable.url = "github:devplayer0/nixpkgs/devplayer0-stable"home-manager-unstable.url = "home-manager"home-manager-stable.url = "home-manager/release-<STABLE>"
- Devshell commands:
update-nixpkgs=nix flake update nixpkgs-{unstable,stable,mine,mine-stable};update-home-manager=nix flake update home-manager-{unstable,stable}. - Validation: prefer
check-system <host>andnix flake check --no-buildover full builds.
Phase 1 — Determine the current NixOS stable
Do this first: everything downstream (the fork's devplayer0-stable rebase target, the flake.nix
stable pins) has to agree on one NixOS stable release, so establish it up front.
- Find the latest NixOS stable release branch — check
git branch -ronupstreamfor the newestrelease-YY.NN, or the NixOS release schedule. - Compare it to
<STABLE>in theflake.nixnixpkgs-stable/home-manager-stableURLs. - If they already match (no new stable): note "stable is current" and carry
<STABLE>into the later phases. - ⏸ If a newer stable has cut: stop and report the coordinated change set before proceeding —
the pieces must all move to the same release together:
- Rebase
devplayer0-stableonto the newupstream/release-YY.NN(Phase 2 uses this target). - Edit
flake.nix:nixpkgs-stable.urlandhome-manager-stable.url→ the new release. - Bump each system's
stateVersion/home.stateVersiononly if the maintainer explicitly wants to — that is a separate, deliberate decision; never auto-bump. Don't editflake.nixhere without confirmation.
- Rebase
Phase 2 — Rebase the nixpkgs fork
For both branches — devplayer0 onto upstream/nixos-unstable, and devplayer0-stable onto
upstream/release-<STABLE> (the release established in Phase 1):
- In
~/documents/projects/nixpkgs, confirm a clean working tree (git status). If dirty, stop and report — don't stash silently. git fetch upstream --pruneandgit fetch origin --prune. If the checkout has been idle a long time this fetch can be large and slow; let it finish.- Enumerate the patch stack before rebasing:
git log --oneline upstream/nixos-unstable..origin/devplayer0(and the stable equivalent againstupstream/release-<STABLE>). For each commit, check whether it has landed upstream or been superseded — e.g.git log --oneline upstream/nixos-unstable -- <path>or grep the upstream tree for the package/option. Note any patch that now looks redundant. - Rebase:
git switch devplayer0 && git rebase upstream/nixos-unstable(and the stable branch ontoupstream/release-<STABLE>).- ⏸ Conflicts: stop. Report which patch conflicts and against what upstream change; let the maintainer resolve, or drop the patch if it has been upstreamed.
- Clean rebase: continue.
- Summarize: which patches still apply, which are now redundant (candidate to drop), which conflicted.
- ⏸ Push: only after confirmation.
git push --force-with-lease origin devplayer0 devplayer0-stable(force needed — rebase rewrites history).
Phase 3 — Update the pinned inputs
Run together (they move as a set):
update-nixpkgs
update-home-manager
Then show the flake.lock diff for the nixpkgs/home-manager entries so the old→new revisions are
visible.
Phase 4 — Sweep version-gated behavior
The repo carries branch-conditional logic and TODOs keyed to specific nixpkgs versions; some become removable after an upgrade, especially after a stable bump. Surface them:
grep -rn "versionAtLeast\|versionOlder\|when 2[0-9]\.[0-9][0-9]\|TODO.*2[0-9]\.[0-9][0-9]" \
--include=*.nix nixos home-manager lib pkgs flake.nix
Known example: nixos/modules/common.nix carries a # TODO: Remove if-else when 26.11 releases
guard. For each hit, evaluate whether the now-current versions make the guard removable and list
candidates. ⏸ Don't delete guards without confirmation — some protect the still-supported stable.
Phase 5 — Review remaining flake inputs
Don't blanket-update. Walk the other inputs deliberately:
- List inputs and locked revisions from
flake.lock(ornix flake metadata). - For each meaningful input (
libnetRepo,devshell,determinate-nix,ragenix,deploy-rs,impermanence, and the packaged apps likeboardie,harmonia,copyparty,sharry, …), compare the locked revision to upstream and summarize notable changes (breaking changes, relevant fixes). Many inputsfollowsnixpkgs-unstableand already moved in Phase 3. - Propose a per-input update list with reasons; update the approved ones with targeted
nix flake update <input>, not a global update.
Phase 6 — Validate
nix flake check --no-build(broad eval; reproduces CI's cheap checks).check-system <host>on a representative box, and one exercising the stable channel if the boxes mix channels.- Report eval/build results honestly. On failure, surface the error and stop rather than papering over it.
Wrap-up
Present a final summary: fork rebase outcome (patches kept/dropped/conflicted), whether a stable
bump is pending or was applied, the lock diff, version-gate cleanup candidates, inputs updated, and
validation results. Leave committing to the maintainer unless asked; if committing, follow the
repo's area/scope: Capitalized summary convention.