bug(prep): a stable rt prep refuses every tag that is not vX.Y.Z, so an adopter with any other tag_format cannot cut #1532
Labels
No labels
bump
major
bump
minor
bump
patch
kind
bug
kind
chore
kind
docs
kind
epic
kind
feature
loop/paused
mirror-drift
priority
critical
priority
high
priority
low
priority
medium
size
L
size
M
size
S
size
XL
status
blocked
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
frankenbit/release-toolkit#1532
Loading…
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?
A stable cut stops in
rt prep's doc-version-refs step whenevertag_formatrenders anything other thanvX.Y.Z. The step has written nothing since #1411 and #1415. Its only remaining behaviour is this refusal.Measured
rtwas built from origin/main8086700(go build ./cmd/rt, reportsrt dev). The scratch adopter repo hadtag_format: 'release-{version}', one tagrelease-0.1.0, oneaddedfragment, and origin set to an unreachable URL.The path, read at origin/main:
internal/config/config.go:241-246:RenderTagsubstitutes{version}intotag_format, so the new tag isrelease-0.2.0.cmd/rt/prep.go:259rendersnewTag.:391-395passes it toprepkg.UpdateDocVersionRefson every stable cut and returns its error. There is no toolkit-self guard.internal/prep/doc_version_refs.go:10issemverTagRE = ^v\d+\.\d+\.\d+$, and:40-41refuses anything else. The rest of the function returns an empty slice on every call (:87).cmd/rt/prep.go:386-390says the step is "toolkit-self only" and "silently no-ops on repos without the toolkit's own README/docs/examples". Neither is true of the call at:391.release-toolkit.yml:24-27says it "runs unconditionally and re-pins README.md + docs/integration.md + examples/". It re-pins nothing.Where it came from. Before
bc30f90(#754, release-toolkit#720, first released in v0.41.0), the same regex lived inscripts/hooks/update-doc-version-refs.sh. That script ran only as apost_bump_hooksentry in the toolkit's ownrelease-toolkit.yml(git show bc30f90^:release-toolkit.yml, lines 30-31). The Go port made it a built-in step. So since v0.41.0, every adopter's stable cut runs the toolkit's own doc-pin tag check.A test pins the refusal as if it were the contract.
cmd/rt/prep_doc_staging_test.go:51-73(TestPrep_docStagingStepIsReached, #1438) runs a stable prep withtag_format: release-{version}and requires it to fail inside "doc version refs". Because the function writes nothing, #1438 used the refusal as the only observable proof that site 8d runs.The documented contract says the opposite.
docs/architecture/contracts/config.schema.json:35-39:tag_formatis a template whose only placeholder is{version}. Nothing restricts the prefix.docs/integration.md:727: "default; only {version} placeholder supported".docs/adr/0003-multi-stage-operator-gate.md:105: a configurable tag format "gives consumers room to use non-standard tag schemes".Census, 2026-10-03. Storey, ember, tmux-tell, cellblock and purser all set
tag_format: 'v{version}', read from each repo'srelease-toolkit.ymlon main. No adopter on this instance is affected today, which is why this is priority/low. Raise it when an adopter wants another prefix.Why it matters
rt prepin the update arm (reusable-release.yml:841), afterrt decidehas already proposed the version, and no rolling PR is ever opened.tag_format.chore(release): prepare release-0.2.0commit lands,rt decidereturnsmode=blocked(pending cut) instead ofmode=cut, because its prepare-subject regex only admitsv?X.Y.Z. That is the sibling issue filed alongside this one (rt decideand non-vtags). Fixing this one alone moves the failure from prep to decide.Decision tree
UpdateDocVersionRefs.rt readme-pin-check --fixnow sets the pins.tag_format: release-{version}gets past this point.prep.go:386-390already claims..forgejo/workflows/reusable-release.ymlexisting, the same condition the bake step uses.tag_formatother thanv{version}at config load.config.schema.json,docs/integration.mdand ADR-0003 are narrowed to match.(a) or (b) belongs with the decide-side sibling. (c) is the honest stopgap if that sibling is deferred.
Acceptance criteria
rt prep --dry-runwithtag_format: 'release-{version}'gets past the doc-refs step;8086700and green after (mutation-verified, AGENTS.md section 8 Axis B);TestPrep_docStagingStepIsReachedis inverted or re-anchored, not deleted.rtrefuses the config before any compose work, the message namestag_format, andconfig.schema.json,docs/integration.mdand ADR-0003 state what is supported.cmd/rt/prep.go:386-390andrelease-toolkit.yml:24-27describe what the code does.Out of scope
rt decide's handling of non-vtags. That is the sibling issue.v*describes elsewhere, which the sibling issue lists:rt prep's own bump and commit walk (internal/prep/git.go:70,80,internal/prep/gitsource.go:71);rt manifest-check(cmd/rt/manifest_check.go:185-188).tag_formata regex and names the retiredrelease-prep.shanddraft-release.sh. That wording is stale whichever option is chosen.Anchor
Found while reviewing PR #1531 / issue #1529 on 2026-10-03. #1531's body lists this under "Not in this PR (each needs its own issue)" as pre-existing. None of the 22 open issues covers it. Related: #1425, #1438, #1411, #1415, #754.
The sibling issue this body refers to is #1533 (
rt decidereads tags and prepare commits asv-prefixed). Both were found while reviewing PR #1531.