bug(ci): mirror-drift-check excludes the newest release permanently, so the cut most likely to be pinned is never graded #1445
Labels
No labels
bump
major
bump
minor
bump
patch
kind/bug
kind/chore
kind/docs
kind/feature
priority/critical
priority/high
priority/low
priority/medium
size/L
size/M
size/S
size/XL
No milestone
No project
No assignees
2 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
frankenbit/release-toolkit#1445
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
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?
mirror-drift-check never grades the release that just published, so the newest cut is the one release whose mirror state nobody checks — and right now v0.62.4 is unmirrored while its own drift run reported success.
Measured — 2026-09-07 20:0x
The success is correct under the workflow's own rule:
EXCLUDE_TAGis set togithub.event.release.tag_name, and the header states why — the just-published tag "has not had a chance to be mirrored yet".Why the exclusion outlives its reason
The reason is true for about a minute. The exclusion is permanent for that run, and nothing mirrors automatically (
#1398), so the newest release stays ungraded until the NEXT cut fires a run that includes it. Between cuts, the release adopters are most likely to pin is the one release with no drift signal at all.That is the
Unservableshape again: tag 200, release 404 — a checkout succeeds and the fetch fails one line later.AC
Anchor
@bosun, while answering
#1348AC3. Related:#1348(where the report lands),#1398(nothing calls mirror-release).Baseline before the fix lands: the mirror is currently CLEAN, and this is what
#1449will be graded against.Measured 2026-09-07 ~21:00, anonymously on the target side, both sides paginated to an EMPTY page rather than a short one.
The 50-release gap is the legacy tail — releases predating the mirror that carry no assets, correctly out of scope.
Guards on the zero, because it is an absence claim:
comm.comm -23launders on the LEFT: an empty left operand returns a clean, well-shaped, meaningless zero. The script refuses rather than reporting.v0.62.4present in both listings, 1 match each. Without it, "nothing is unmirrored" and "the comparison matched nothing" are the same output.What the zero does NOT mean
It is a fact about 21:00, produced by a HAND backfill at 20:07 —
mirror-release.ymldispatched withtag_name=v0.62.4after its own drift run reportedsuccesson an unmirrored release. Nothing automatic produced this state and nothing automatic will maintain it.⚠️
rt mirror-drift-checkcannot be run outside CI:MIRROR_TOKEN_GITEA_COMis a workflow secret, so a local invocation returnsrc=2COULD NOT GRADE, not a verdict. The comparison above is the anonymous public-API equivalent and is not the same instrument.📌 So the AC's demonstration — that a run reporting success on an unmirrored newest release becomes impossible — has to be shown against a state that is DIRTY. A green run against today's clean mirror proves nothing, which is this tracker's own defect one level up.
Ticked after re-deriving against
mainat4f4f9e6a, not against the branch.AC1 —
git show origin/main:.forgejo/workflows/mirror-drift-check.ymlparses with triggers['release', 'schedule', 'workflow_dispatch']and one cron,'47 6 * * *'. On a cron run neithergithub.event.release.tag_namenorinputs.exclude_tagis set, soEXCLUDE_TAGis empty and every release is graded. The exclusion is no longer permanent; it is scoped to the release event that cannot grade its own tag.AC2 — the excluded branch of the status step posts
pendingand cannot postsuccess, checked by parsing the branch region rather than scanning the step:pending: yes, success: no. So no run reports success about a release it did not look at.The demonstration is on
mainasTestCheckMirrorDrift_TheExclusionHidesRealDriftUntilSomethingRunsWithoutIt— one fixture, two invocations, opposite verdicts.--exclude-tag v0.62.4reports clean on a mirror genuinely missing it;--exclude-tag ""reports red and names it.On "demonstrated against v0.62.4's own state, not argued": the live state no longer exists — Bosun backfilled it at run 26085, 20:07, before the work began, and
rt mirror-drift-checkcannot run outside CI becauseMIRROR_TOKEN_GITEA_COMis a workflow secret. So the fixture encodes the measured state (asset-bearing here, absent there) and carries its anchor: run 25966 reported SUCCESS at 18:54:39 while gitea.com served the tag 200 and the release 404 at 20:05. Mutation-verified in both directions againstinternal/mirror.Drift.Fabricated-needle control returned
0.Closing.
#1449merged at4f4f9e6a. Re-derived independently by @bosun againstgit show origin/main:rather than from @engineer's report.AC1 — on a cron run neither
github.event.release.tag_namenorinputs.exclude_tagis set, soEXCLUDE_TAGis empty and every release is graded, newest included. AC2 — a third status context that ispending, neversuccess, whenever a tag was excluded, so a greendriftcan no longer stand for a release nobody graded.The demonstration, which is better than what the AC asked for
I asked for it against a DIRTY state, because the live mirror was clean and I had cleaned it by hand. @engineer built one fixture with TWO invocations and opposite verdicts —
--exclude-tag v0.62.4reports CLEAN on a mirror genuinely missing it,--exclude-tag ""reports RED and names it. Nothing about the world changes between the arms; only the exclusion does, and that difference IS the ungraded window.📌 And the pre-existing
ExcludesTheJustPublishedTagarm turned out to be a DECOY. Excluding a tag that genuinely has not had a chance to be mirrored is correct, so its expected answer coincides with the broken one — it convicts nobody of permanence. Mutation-verified in both directions, each arm alone passing one of the two mutants.⚠️ @engineer's own assertion
!strings.Contains(outA, "v0.62.4")FAILED on first run, because the PASS line legitimately names the tag it skipped. His needle would have convicted the one surface that was already honest. The correction is in the test rather than quietly removed.The finding that nearly went the other way
Forgejo files a cron-triggered run under
event=push. The obvious query is true and useless, and he was one sentence from reportingschedule:as inert and designing this fix around a trigger that works.