fix(ci): reject kernel tags cut from a stale checkout #27
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "fix/stale-tag-guard"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Problem
Tagging without pulling first produces a valid tag on an old commit, and
build-kernel.ymlthen goes green while silently losing two properties:configs/seeds/<X.Y>.tomlas of the tagged commit. Seed bumps land onmainas mergedseed-bump.ymlPRs between builds, so a stale tag can build the previous baseline — or a cross-series fallback seed aftermainhas already advanced to a real same-line seed. The seed sets every un-pinned hardening default, soconfigs/intent.configstays satisfied and the fidelity assertion catches nothing.releases/in the tag's own tree, and each release dir arrives via thepublish:commit that follows its build. A tag predating the first publish of its line finds no baseline and logsskipping— so the one check that would have caught (1) is disabled by the same mistake.v7.1.5-hardened1hit exactly this. Cut from9bffa1b, it is missing 8 commits including both seed bumps: still pinned to7.0.12.hardened1-1(the cross-series fallback) whilemaincarries the real7.1.4.hardened1-1seed anthraxx finally shipped. Its tree has noreleases/v7.1.*dir, so drift checking is skipped.Change
build-kernel.yml— newassert tag is current with mainstep after checkout, assertingorigin/mainis an ancestor of the tagged commit. On failure it prints the missing commits and the exact delete-and-re-cut recipe.Hard failure rather than a warning: both symptoms are invisible in a green log, and a
::warning::scrolls past in a 40-minute build. Repo variableALLOW_STALE_TAG=1downgrades it to a warning for a deliberate rebuild of an old commit, mirroring the existingREQUIRE_NET_ISOLATIONescape hatch.The
mainref is fetched with an explicit destination refspec (+refs/heads/main:refs/remotes/origin/main) rather than the baregit fetch origin main, becauseactions/checkoutrunning against a tag may configure a tag-only fetch refspec, which would leaverefs/remotes/origin/mainabsent.cve-watch.yml— the tracking-issue body said "tag and push" with no pull, which is what caused this. It now leads withgit pull --ff-onlyin a fenced block, explains why the pull is load-bearing, and carries the recovery steps.docs/operators/config-architecture.md— same fix to the routine-bump recipe.Verification
v7.1.5-hardened1→ stale, guard fires; a temp tag atorigin/main→ current, guard passes.origin/main.yamllint -d relaxed .forgejo/workflows/exits 0; bothworkflow-expressionsgreps fromvalidate.ymlpass (no expression templates in the new comments — the failure mode that once brokecve-watch.yml);shellcheck build/*.sh tools/*.shclean.cve-watchissue body end-to-end with template expressions substituted, confirming literal backticks and correct markdown.Follow-up (not in this PR)
configs/seeds/7.1.tomlonmainis now pinned to7.1.4.hardened1-1, but its header comment still claims anthraxx "has not published a 7.1 config.x86_64 yet" and that the line is seeded from 7.0.12.bump-seed.shrewrites the pin values but not the surrounding prose (it also collapsed thecommit/tagkey alignment). Worth a separate fix.🤖 Generated with Claude Code
Tagging without pulling first produces a valid tag on an old commit, and build-kernel.yml then goes GREEN while silently losing two properties: 1. It uses the configs/seeds/<X.Y>.toml pin as of the tagged commit, not the current one. Seed bumps land on main as merged seed-bump.yml PRs between builds, so a stale tag can build the previous baseline -- or a cross-series fallback seed after main has already advanced to a real same-line seed. The seed sets every UN-pinned hardening default, so the fidelity assertion stays satisfied and catches nothing. 2. It skips the hardening-drift guard. That step resolves its baseline from releases/ in the tag's own tree, and each release dir arrives via the `publish:` commit following its build -- so a tag predating the first publish of its line finds no baseline and logs "skipping". The one check that would have caught (1) is disabled by the same mistake. v7.1.5-hardened1 hit exactly this: cut from9bffa1b, it is missing both seed bumps (still pinned to the 7.0.12 fallback while main carries the real 7.1.4 seed) and has no 7.1 release dir, so drift checking is skipped. Add an ancestry assertion right after checkout. Hard failure, not a warning: both symptoms are invisible in a green log and a WARNING scrolls past in a 40-minute build. Repo variable ALLOW_STALE_TAG=1 downgrades it to a warning for a deliberate rebuild of an old commit, mirroring REQUIRE_NET_ISOLATION. Also close the loop on the instructions that caused it -- the cve-watch tracking issue and the operator bump recipe both said "tag and push" with no pull. Both now lead with `git pull --ff-only` and carry the delete-and- re-cut recovery steps. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>