feat(renovate): auto-refresh pinned Nix FOD hashes on dep bump (RIG-2727) - #626
Open
rigel-mintaka wants to merge 3 commits into
Open
feat(renovate): auto-refresh pinned Nix FOD hashes on dep bump (RIG-2727)#626rigel-mintaka wants to merge 3 commits into
rigel-mintaka wants to merge 3 commits into
Conversation
…727) A Renovate dependency bump moves a pinned Nix fixed-output-derivation (FOD) hash, but nothing regenerates it — so the bump PR fails CI on `hash mismatch in fixed-output derivation` and can't land without a manual hand-fix. PR #579 (`golang.org/x/net` → v0.56.0 security bump) hit exactly this: its `Gates (moon + pgtest)` job failed building `compass-guestd-go-modules.drv` because the gomod change moved the Go module set but left `guest-image/default.nix`'s pinned `vendorHash` stale. Compass pins exactly two FOD hashes outside the vendored `forks/` trees: - Go `vendorHash` (buildGoModule compass-guestd) in `guest-image/default.nix` — moved by a `go/go.mod` | `go/go.sum` bump (gomod manager). - bun `outputHash` (recursive FOD of `bun install`) in `agent-image/entrypoint.nix` — moved by a `bun.lock` bump (bun/catalog manager). Neither is a URL hash `nix store prefetch-file` can recompute (that is `refresh-toolchain-hashes.ts`'s job for the vendored-binary pins). A `vendorHash`/`outputHash` is only knowable by realising the derivation. `tools/renovate/refresh-fod-hashes.ts` self-gates per FOD on its trigger manifest, fakes the pin to force the mismatch, builds the guest-image rootfs vehicle (which realises both FODs, failing fast at the FOD before the heavy compile/pack), parses the reported `got:` SRI for that derivation, and writes it back — so the bump PR lands green. Wired at two sites to survive Renovate's winner-take-all per-branch task slot: top-level `postUpgradeTasks` (branch mode — gomod and bun/npm-first branches) and the catalog `packageRule` (update mode — catalog-first branches, where the collapsed branch config evicts the top-level branch task). One command string → one anchored `allowedCommands` entry. Guarded by `config.test.ts` (command↔allowlist coupling, both-site wiring, fileFilters coverage) and a `refresh-fod-hashes.test.ts` regression suite. Verified end-to-end against real nix: the shipped script recomputes both hashes to their exact committed values. Spec-impact: none. Refs #579. Refs RIG-2727 Co-authored-by: Matt Wilkinson <matt@rigel.build>
|
Compass engineering docs preview: https://compass-repo-rig-2727-renova.compass-eng-docs.pages.dev Deployed from |
Review-loop fixes on PR #626, additive over the submitted tip: - Document the verified biome/devenv-channel FOD-refresh exemption. The devenv-nixpkgs lockstep branch rewrites bun.lock + the biome catalog pin but intentionally omits the FOD refresh; biome is a root-only devDependency absent from compass-agent's filtered `bun install --filter '@compass/agent'` tree (verified: not in node_modules nor .bun), so a channel bump cannot move agent-image/entrypoint.nix's outputHash. Pinned by an explicit config.test.ts guard so a future biome-in-compass-agent change forces a revisit. - Correct the catalog-rule comment: the per-upgrade FOD refresh leg is idempotent but NOT free (it re-realises the node_modules FOD once per catalog upgrade). Kept last-write-wins; noted why a same-branch short-circuit is unsafe without relying on Renovate's grouped-update apply ordering. - Make the got:-SRI parse robust: scan from the mismatch header to the next header instead of a fixed 5-line window, so a future nix that adds context lines before `got:` can't silently wedge every FOD build. Add window-boundary + no-cross-block-bleed tests. - Write the recomputed SRI literally (function replacer) so a `$`-bearing value can never be interpreted as a replacement pattern. Add a literal-write test. Co-authored-by: Matt Wilkinson <matt@rigel.build>
…IG-2727)
Round-2 review low finding: parseGotForFragment attributes a nix mismatch
block to a FOD by `drvName.includes(fragment)`. Safe for the current two
fragments ("go-modules"/"node-modules", mutually disjoint), but a future
FOD_ENTRIES edit adding an ambiguous fragment (e.g. a bare "modules") would
silently misattribute a got: SRI and write the wrong hash.
Add a module-load assertion that no drvFragment is a substring of another, so
such an edit fails loud at import rather than misattributing at runtime, plus a
test stating the invariant.
Co-authored-by: Matt Wilkinson <matt@rigel.build>
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.
A Renovate dependency bump moves a pinned Nix fixed-output-derivation (FOD) hash, but nothing regenerates it — so the bump PR fails CI on
hash mismatch in fixed-output derivationand can't land without a manual hand-fix. PR #579 (golang.org/x/net→ v0.56.0 security bump) hit exactly this: itsGates (moon + pgtest)job failed buildingcompass-guestd-go-modules.drvbecause the gomod change moved the Go module set but leftguest-image/default.nix's pinnedvendorHashstale.Compass pins exactly two FOD hashes outside the vendored
forks/trees:vendorHash(buildGoModule compass-guestd) inguest-image/default.nix— moved by ago/go.mod|go/go.sumbump (gomod manager).outputHash(recursive FOD ofbun install) inagent-image/entrypoint.nix— moved by abun.lockbump (bun/catalog manager).Neither is a URL hash
nix store prefetch-filecan recompute (that isrefresh-toolchain-hashes.ts's job for the vendored-binary pins). AvendorHash/outputHashis only knowable by realising the derivation.tools/renovate/refresh-fod-hashes.tsself-gates per FOD on its trigger manifest, fakes the pin to force the mismatch, builds the guest-image rootfs vehicle (which realises both FODs, failing fast at the FOD before the heavy compile/pack), parses the reportedgot:SRI for that derivation, and writes it back — so the bump PR lands green.Wired at two sites to survive Renovate's winner-take-all per-branch task slot: top-level
postUpgradeTasks(branch mode — gomod and bun/npm-first branches) and the catalogpackageRule(update mode — catalog-first branches, where the collapsed branch config evicts the top-level branch task). One command string → one anchoredallowedCommandsentry. Guarded byconfig.test.ts(command↔allowlist coupling, both-site wiring, fileFilters coverage) and arefresh-fod-hashes.test.tsregression suite. Verified end-to-end against real nix: the shipped script recomputes both hashes to their exact committed values.Spec-impact: none. Refs #579. Refs RIG-2727
Co-authored-by: Matt Wilkinson matt@rigel.build