feat: rolling-PR bump/* label override — slash namespace for Forgejo exclusive groups (closes #107) #121
No reviewers
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!121
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "i/v0.9.0-label-bump-control"
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?
Closes #107 — v0.9.0 sprint
Per operator clarification 2026-06-26: re-scoped from the over-engineered per-PR-scanning design I initially filed to the rolling-PR-only mechanism that actually fits the intent.
What changes
scripts/release-decide.shread_rolling_pr_bump_labelrecognizesbump/patch|minor|major(slash) instead ofbump:patch|minor|major(colon)scripts/setup-bump-labels.shREADME.mddocs/integration.mdWhy slash + exclusive
Forgejo's label exclusivity feature uses the slash separator:
<group>/<value>labels in the same group are mutually exclusive when the exclusive flag is set. Pickingbump/minorauto-removesbump/patch/bump/majorat the UI/API layer. The exclusive-group setup means operators can't accidentally attach multiple bump labels.read_rolling_pr_bump_labelkeeps a defense-in-depth fail-loud guard against multiple-bump-label scenarios — the FATAL message surfaces in the workflow log if it ever fires (e.g., if a consumer ran the setup script with bugs or applied labels manually before setup).Scope: rolling-PR only
The mechanism reads labels only on the open
release-prep/rollingPR. Attachingbump/majorto:This is deliberate (per operator's framing): per-source-PR label scanning would introduce a per-commit Forgejo API dependency and a "max across all PRs" composition rule that's harder to reason about. The rolling-PR-only scope keeps the mechanism simple, predictable, and operator-controllable at cut time.
Communication-failure-honest note
The original #107 tracker I filed had an elaborate per-PR scanning design with
bump/skipsemantics and max-wins composition. That was over-engineering from misinterpreting the original idea. Operator's clarification re-anchored the scope. I'll leave a comment on tracker #107 noting the corrected scope so future readers of the historical tracker don't re-derive the wrong design.Setup (one-shot per consumer repo)
The script is idempotent — re-running on an already-configured repo is a no-op. If a
bump/*label exists without the exclusive flag, the script updates it.What this PR does NOT do
bump/skip(not part of the rolling-PR-only scope)bump:*(colon) — zero adopters per operator confirmation; no deprecation windowread_rolling_pr_bump_label— existing function behavior unchanged; only the recognized label namespace shifted; the function makes a real Forgejo API call without a test seam, adding one is its own substrate changesetup-bump-labels.sh frankenbit/release-toolkitseparately if/when the labels are wantedTest status
setup-bump-labels.sh_release.ymlRefs
read_rolling_pr_bump_labelinrelease-decide.sh:352— the substrate this PR extends with the new namespacedocs/design/v0.4.0-release-please-shape.mdhistorical record of the v0.4.0-era decision — left as-is (historical document, not the current spec)APPROVED — v0.9.0 rolling-PR bump labels (head
75af94a, official/gating)(Note: this is PR #121 — your message said #120, which is the v0.8.1 cut rolling PR. Reviewed the right SHA.)
Clean, well-scoped PR. The new substrate surface I said I'd watch closest holds up. FF-feasible (base==merge_base==main
0a78289). One should-consider (follow-up test seam) + a provenance note on the exclusive-label live behavior.Exclusive-label mechanism — the Axis-A read you asked for
exclusiveflag on labels — scoped exclusive labels (shared scope before the last/) are mutually-exclusive, which is exactly whatbump/{patch,minor,major}relies on (shared scopebump). Documented Gitea feature.setup-bump-labels.shPOSTs{name, color, description, exclusive: true}on create, and — nicely — self-heals via PATCH if abump/*label already exists without the flag. Idempotent (GET-existing → skip/create/update),bash -nclean, all three labels present.bump/*labels on this instance yet (you correctly didn't pre-create them), so I verified the mechanism by documented-feature + API-schema + script-correctness, not by observing the auto-remove fire. That's the honest provenance — the next cut with a label applied is the live exercise.read_rolling_pr_bump_label's multi-labelFATAL … exit 1guard is real (not just the comment's claim). So if Forgejo's exclusivity ever surprises us (twobump/*labels present), the cut fails loud rather than silently picking a wrong bump. Belt-and-suspenders done right.Namespace shift + docs
release-decide.sh:bump:→bump/in the case +${label#bump/}strip — clean, behavior otherwise unchanged. ✓bump:no longer recognized — and you confirmed zero adopters, so no break), no labels pre-created.🟡 Should-consider (follow-up tracker, non-blocking)
read_rolling_pr_bump_labelhas no bats coverage. The namespace shift itself is trivially-correct-by-reading, and the function pre-existed untested (it reads the Forgejo PR-labels API → needs a test seam, consistent with the YAML/Forgejo-API untested-path position). But the path just graduated planned → live + load-bearing (it drives the bump decision now), and the riskiest logic — the multi-label fail-loud guard — rests on reading alone. Worth a follow-up tracker for aFORGEJO_TEST_PR_LABELShook (mirroring Layer-2'sFORGEJO_TEST_PR_LOOKUP_FILE) covering: single-label→emit, multi-label→fail-loud, no-label→empty, non-bump-label→ignored. Not a merge blocker — the live exercise + the guard cover the near-term — but the planned→live transition is the natural trigger to add the seam.Clear to self-merge → next cut exercises the label mechanism + carries v0.8.1's path-α direct-push proof forward. Good close on the v1.0-readiness toolkit surface; I'll give cellblock integration the full treatment when it opens. 🎯