fix(nix): correctly qualify flake input refs as tags or branches - #45000
Draft
mglazer wants to merge 1 commit into
Draft
fix(nix): correctly qualify flake input refs as tags or branches#45000mglazer wants to merge 1 commit into
mglazer wants to merge 1 commit into
Conversation
When the nix manager rewrites a flake input's `ref=` query param (e.g. bumping `ref=some-branch` to a newer value), it currently substring-replaces the old ref value with the new one, keeping whatever refs/heads//refs/tags/ qualifier (or lack of one) the old ref happened to have. This breaks when the new value resolves to a different ref namespace than the old one, e.g. bumping an unqualified branch ref to a value that only exists as a tag upstream. Nix's git fetcher resolves a bare or mis-qualified ref via refs/heads/<ref> only, with no fallback to refs/tags/, so `nix flake lock`/`nix flake update` then fails with "fatal: couldn't find remote ref refs/heads/<ref>" even though the ref exists as a tag. Thread the git-refs datasource's own knowledge of each ref's actual type (tag vs branch) through lookup generation into the nix manager, and use it to decide the correct qualifier when rewriting a flake input URL, falling back to the old ref's shape when that information isn't available. This also reintroduces a nix-specific updateDependency implementation: without one, the generic auto-replace fallback cannot reliably locate and rewrite a flake input's `ref=`/`rev=` query params together, and throws for the common case of a flake input pinning both a ref and a rev.
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.
Changes
When the nix manager rewrites a flake input's
ref=query param (e.g. bumpingref=some-branchto a newer value), it substring-replaces the old ref value with the new one while keeping whateverrefs/heads//refs/tags/qualifier (or lack of one) the old ref happened to have.This breaks when the new value resolves to a different ref namespace than the old one — for example, bumping an unqualified branch ref to a value that only exists as a tag upstream. Nix's git fetcher resolves a bare or mis-qualified ref via
refs/heads/<ref>only, with no fallback torefs/tags/, sonix flake lock/nix flake updatethen fails with:even though the ref exists as a tag (or vice versa).
This PR:
gitRefType('tags' | 'heads') toRelease, populated by the git-refs datasource from the actual remote refs it already fetches (preferring'tags'when a value is ambiguous, matching Nix's own resolution order).gitRefTypethroughgenerateUpdate→LookupUpdate→Upgrade, so managers can see how a candidate new version actually resolves upstream.updateDependency(it didn't previously exist; nix relied on the generic auto-replace fallback). Without it, auto-replace can't reliably locate and rewrite a flake input URL'sref=/rev=query params together and throws for the common case of an input pinning both a ref and a rev.updateDependencyusesgitRefTypeto decide the correct qualifier when rewriting a flake input URL, falling back to the old ref's own shape (qualified or bare) when that information isn't available, so behavior for datasources/managers that don't setgitRefTypeis unchanged.Context / repro
Repro'd locally with real
nix(Determinate Nix 2.33 / upstream 2.18+): a flake input pinned viaref=v20.0.0wherev20.0.0exists only as a tag on the remote fails identically:while
ref=refs/tags/v20.0.0resolves correctly. Also confirmed that without a nix-specificupdateDependency, the generic auto-replace path throwsWORKER_FILE_UPDATE_FAILEDfor a flake input pinning bothref=andrev=when bumping to a new value, since it can't locate a singlereplaceString/currentValuecovering both.Tests
lib/modules/manager/nix/update.spec.ts(12 cases): bare ref → tag, bare ref → branch, stale-qualifier correction, tag→tag preservation, no-gitRefTypefallback,github:shorthand handling, digest-only updates, and not-found/unparseable-URL edge cases. 100% statement/line coverage on the new file.lib/modules/datasource/git-refs/index.spec.tssnapshot for the newgitRefTypefield.lib/modules/manager/nix/,lib/modules/datasource/git-refs/,lib/workers/repository/process/lookup/, andlib/workers/repository/update/branch/— all passing, no regressions.