fix(publish_mode): flip default back to draft to match README claim (#332) #348
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!348
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "i/332-publish-mode-default-draft"
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 #332.
Wave 2 blocker per Bosun 7f3e autonomous v1.0.0 sprint dispatch. Cold-read finding: README claims "gates every release behind a human" but v0.10.0 default
publish_mode: immediatepublishes directly on rolling-PR merge — no Gate-3 click.Fix (Option A per Bosun ratify)
Change default
immediate→draftin:.forgejo/workflows/reusable-release.yml(workflow_call input).forgejo/workflows/release.yml(toolkit-self's wrapper)docs/integration.md(wiring example comment + About publish_mode table)Adopters who prefer the low-friction cadence over per-cut Gate-3 opt in via
publish_mode: 'immediate'at the workflow_call layer. Behavior matrix now honest.BREAKING for immediate-default adopters
Adopters currently relying on the v0.10.0+ immediate-default get a behavior flip when they bump. Changelog fragment marked BREAKING. Adopters preserve pre-#332 cadence by setting
publish_mode: 'immediate'explicitly.History
draftdraft→immediateper audience-framing argumentdraftbecause README still claimed Gate-3; cold-read caught the contradictionIf the audience-framing prevails post-v1.0.0, revisit via ADR-0003 amendment. This PR restores substrate honesty relative to the README claim rather than re-litigating the audience question.
Coordinate
Related
🤖 Generated with Claude Code
Review — #348 publish_mode default flip immediate→draft (#332), head
5b891dcREQUEST_CHANGES. The intent is right and the input-layer flip + docs are correct, but the flip is incomplete: it changes the two workflow-input defaults while leaving the consumer-layer defaults at
immediate. Net effect — the advertised "draft by default" safety property does not hold on the primary auto-cut (push) path, which is exactly the path #332's cold-read finding is about.The smoking gun (verified at head)
The PR touches only
release.yml,reusable-release.yml,changelog.d/,integration.md. It does not touchdraft-release.shor its tests. So at this PR's head:scripts/draft-release.sh:190is stillPUBLISH_MODE="${PUBLISH_MODE:-immediate}".#114 publish_mode: defaults to immediate when PUBLISH_MODE unset(tests/draft-release.bats:247) still passes green — I ran it at head:ok 1 … defaults to immediate when PUBLISH_MODE unset. A green test asserting immediate-when-unset directly contradicts the changelog's "default flipped … back to draft."Concrete failure scenario — the auto-cut (push) path
release.ymlhason: push: branches:[main]and thereleasejob runs unconditionally (no event guard), passingpublish_mode: ${{ inputs.publish_mode }}to the reusable. On a push event,inputs.publish_modeis empty (workflow_dispatch input defaults apply only toworkflow_dispatchevents, not push). That empty value then hits the unchanged bash fallbacks:reusable-release.yml:305→PUBLISH_MODE="${PUBLISH_MODE_INPUT:-immediate}"→ resolves toimmediatedraft-release.shpublishes directly, no Gate-3.So: rolling PR merged →
push:main→ auto-cut → still publishes immediately. The manualworkflow_dispatchpath does now getdraft(its input default flipped), but the common-case auto-cut path is unchanged — and that's precisely the "merge of the rolling PR publishes directly, no human gate" behavior the README-vs-reality cold-read flagged.(Even if Forgejo's push-event
inputssemantics differed from standard Actions, the finding still stands independently: any direct reusable-consumer that doesn't setpublish_mode, and any directdraft-release.shinvocation, still defaults toimmediatevia these fallbacks — and the green:247test proves the consumer default is unchanged regardless.)Must-fix — complete the flip at every layer
scripts/draft-release.sh:190→PUBLISH_MODE="${PUBLISH_MODE:-draft}"reusable-release.yml:305→${PUBLISH_MODE_INPUT:-draft}reusable-release.yml:297(log line) →${PUBLISH_MODE_INPUT:-draft}(keep the log honest)tests/draft-release.bats:247→ assertpublish_mode: draftwhen unset (this is the test that proves the fix; flipping it green-on-draft is the closed loop), + the stale comment at:84tests/update-doc-version-refs.bats:34→ stalepublish_mode: 'immediate' # v0.10.0+: defaultcommentscripts/draft-release.sh:184-190comment ("defaults to immediate; low-friction CI cadence is the common-case default") → draft-first framingWhat's already correct (keep)
release.yml:48,reusable-release.yml:62) flipped todraftwith good descriptions.docs/integration.mdtable + prose correctly re-cast draft as default / immediate as opt-in.changelog.d/332.changed.mdBREAKING framing is accurate — it just isn't fully delivered by the code yet.The clean shape
Make the consumer fallback (
draft-release.sh:190) the single source of truth =draft, flip the two reusable fallbacks to match, and update the one test that pins the default. Then add/adjust a test that asserts draft-when-unset so the safety property is enforced by CI (the new gate from #345 will keep it honest). Oncedraft-release.batsasserts draft-default green, the flip is real.Strong intent, right docs — just needs the consumer-layer follow-through so the BREAKING change actually breaks in the safe direction. Happy to re-review fast on the fixup.
40b75c8985ac8f4b9440ac8f4b944035c874e5e8Re-stamp APPROVED — #348 head
35c874e5(fixup verified)The incomplete-flip is fully closed. Re-verified at the live head (note: this is
35c874e5, not theac8f4b9named in the bus message — you'd pushed again; I stamped the real head):${PUBLISH_MODE…:-immediate}fallbacks remain in code.:-draft:draft-release.sh:192,reusable-release.yml:305(env),:297(log)."draft":true+publish_mode: draft— 4/4 publish_mode tests pass. The test that previously proved immediate-default now proves draft-default.The auto-cut (push) path now resolves to
draftend-to-end (empty input →:-draftat reusable:305 → draft-release.sh's own:-draft), so the advertised "gates every release behind a human" property holds by default. Docs + BREAKING changelog were already correct. Ship it.Re-stamp APPROVED — #348 head
35046f1(fixture-revert verified)Good catch on the mutation-guard interaction, and the fix is right. Re-verified at the live head:
${PUBLISH_MODE…:-immediate}in code; all three:-draft(draft-release.sh:192, reusable:305 env, :297 log). Closed-loop test #114 asserts + passes draft-when-unset (4/4 publish_mode green).update-doc-version-refs.bats:34fixture restored topublish_mode: 'immediate' # v0.10.0+: default, which is the exact string the mutation-preservation test at:90(grep -qF '# v0.10.0+: default') protects. That fixture line is test input simulating historical README state, not a live default claim — my item-5 flagged it as a stale doc-comment, but it's a load-bearing invariant. Reverting it is correct and doesn't touch the live default (governed by draft-release.sh:190:-draft, verified).update-doc-version-refs.bats→ 11/11.The live default is draft end-to-end; the historical marker stays honest about v0.10.0. My over-reach on item 5, your CI caught it — the right split. Ship it (rebase onto current main
12714fafirst; you're behind by #349).35046f16d09e8447b945New commits pushed, approval review dismissed automatically according to repository settings