feat(single-stack): port setup-bump-labels.sh to rt setup-bump-labels #776
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
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
frankenbit/release-toolkit#776
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?
Motivation
scripts/setup-bump-labels.sh— 86 lines — creates thebump/{patch,minor,major}labels ona Forgejo repo as an exclusive group (Forgejo then enforces single-select, so picking
bump/minorauto-removesbump/patch). It is idempotent: it skips labels already correct andupdates ones missing the exclusive flag.
It is one of five bash files left on
main(1,789 lines total) and it is the clearest port ofthe remainder. Everything it does is already Go's domain here: argument parsing, a
GET /labelsread, conditionalPOST/PATCH, and a comparison. The Forgejo client that#705partB lands makes this nearly mechanical.
🔑 It is ADOPTER-FACING, which decides where it lands on the CLI surface
Referenced from
docs/integration.mdand three architecture documents — never from aworkflow. It is a setup verb an adopter runs once against their own repo, not toolkit-self
machinery.
So it belongs in the adopter half of the surface, unlike
check-self-bootstrapandbinary-size-check(see#774). Porting it makes the adopter verb count 17, not 16 — andthat is a real change to the C5 contract, not a bookkeeping one.
✅ The port REMOVES a bug class rather than relocating one
The script hand-rolls keeping the token out of
curl'sargv(release-toolkit#371):In Go the token is a field on a request object and never becomes a process argument, so the
temp-file dance, the mode, the trap and every path that could skip the trap all cease to
exist. That is a structural close, not a reimplementation.
⚠️ It also carries a duplicated guard —
FORGEJO_TOKENis checked for emptiness twice,at two different lines, with two different message formats. Harmless, and a tell that the file
has been edited by more than one pass.
Scope
rt setup-bump-labels OWNER/REPO, adopter-facing, registered in the adopter half ofmain.go'ssubcommandssliceflag was missing) · already correct. Do not collapse them into one success line — see
/srv/CLAUDE.md§a scope note inside a success message is decorationread_rolling_pr_bump_label's defence-in-depth guardagainst multiple bump labels stays as it is
FORGEJO_BASE_URLdefault andFORGEJO_TOKENrequirement unchangedscripts/setup-bump-labels.sh; updatedocs/integration.mdand the three architecturereferences in the same PR
Acceptance criteria
rt setup-bump-labels OWNER/REPOcreates the three labels as an exclusive group on a repo that has nonebump/*labels exist WITHOUT the exclusive flag is updated, and that outcome is distinguishable from both othersscripts/setup-bump-labels.shis deleted and no doc still points at itdocs/architecture/contracts/cli-surface.md) reflects the new adopter verbRelated
#705— retire the last bash (forgejo-api.sh); lands the Forgejo client this depends on#774— the subcommand slice is a superset of the C5 contract; this adds an ADOPTER verb, which is the opposite direction from the two toolkit-self verbs in dispute there#371— token-out-of-argv, the guard this port makes unnecessary#107— the label-based bump-control mechanism itselfAnchor
2026-08-20 09:23, operator scoping of the bash-retirement remainder: "setup-bump-labels.sh looks
like it has some logic and some curl calls for web access. Both are in the domain of Go, I
guess?" — correct, and the adopter-facing finding is what decides its placement. Census measured
recursively against
origin/main: 5 files, 1,789 lines.ACs ticked — verified, including the two that a passing test suite does not establish
🔑 The last one is the AC the port EXISTS to satisfy and it is now structural rather than
disciplined. The bash hand-rolled
mktemp+install -m600+trapto keep the token out ofcurl's argv (#371). In Go there is no argv to keep it out of — 0 exec calls, so the wholeclass is unreachable rather than merely avoided.
📌 The idempotence and exclusive-group ACs rest on @pilot's 7 tests plus @surveyor's
byte-identical label-value differential against the bash — which she ran before the merge
deleted the source of truth she was comparing against. That comparison is no longer possible;
it was run at the only moment it could be.