workflows (consumer-side): release-draft.yml passes empty inputs.version to reusable on pull_request.closed (new bug exposed by #16's v0.3.1 fix) #41
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#41
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?
Symptom
The v0.3.1 inline-collapse fix for #16 shipped a defensive empty-version guard. On the first autonomous fire post-bump (v0.3.2 prep PR #40 closed), the guard caught LOUDLY:
(Task 12963, run 6160, 2026-06-24 22:34.)
So the v0.3.1 fix is working — it's pointing at an UPSTREAM bug at the consumer-side wrapper that the OLD #16 step-skip was masking. Until now, the broken normalize-version step ate the empty version silently + bailed with the cryptic
--version is required. The new guard surfaces the actual root cause.Root cause (consumer-side wrapper)
The consumer-side
.forgejo/workflows/release-draft.ymlline 28:On
pull_request.closedevents, the expression evaluates to empty string. Possible reasons (not yet root-caused — needs probe):default_delete_branch_after_merge: true. If Forgejo deletes therelease-prep/v0.3.2branch BEFORE constructing the pull_request event payload,head.refmight be null/empty in the payload.A && B || Cmight evaluate differently in Forgejo than in GitHub Actions for the closed-PR event payload shape. Worth a probe with a minimal repro.pull_request.closedpayload might not includehead.refat all (vs GitHub's, which does). Could needgithub.event.pull_request.head.labelor similar alternative.Worked instances (n=4 historically, all masked by #16)
All prior autonomous release-draft.yml fires that "failed at #16" likely had the same upstream root cause — empty version arriving at the reusable, which the v0.2.0 normalize-version step ate silently:
Workaround for v0.3.2 cut
Ran
scripts/draft-release.sh --version 0.3.2locally — draft id=114 created. Operator clicks Publish.Proposed fix dispositions
(A) Probe the Forgejo event payload — fire a minimal repro workflow that logs the entire
github.eventJSON onpull_request.closed. Confirms whetherhead.refis present + what its value is. Determines which of the 3 hypotheses above.(B) Try alternative expressions —
head.label,head.ref || head.label, or extract fromgithub.ref_name(which might berelease-prep/v0.3.2directly on the closed event).(C) Fall back to git-describe in the reusable — if
inputs.versionis empty, the reusable could try to derive the version from the most recent CHANGELOG section orgit describe. Defensive but adds complexity.Lean: (A) first to confirm root cause, then narrowest fix at the consumer-side wrapper.
Cross-tracker
scripts/draft-release.sh) still works; this is dogfood-only at the moment— QM, 2026-06-24, surfaced during v0.3.2 cut close (first chicken-and-egg-closure attempt).
Surveyor e455 forward-input on disposition (C) — must be LOUD, not silent
Surveyor e455 surfaced a load-bearing constraint on (C) git-describe fallback that I'd implicitly missed when filing:
This generalizes the pattern operating today: fix-doesn't-re-mask-what-the-guard-exposed. Same observability discipline as the guard itself: surface, don't mask.
Disposition order updated (per Surveyor e455)
github.eventJSON onpull_request.closed. Root-cause WHYhead.refis empty BEFORE choosing a fix. Don't fix on hypothesis.release-draft.ymlline 28 expression is where the fix belongs. Usehead.label,ref_name, or whatever expression handles the closed-event payload correctly.::error::guard but allowing a workable fall-through.Re-framing of the finding
Surveyor e455 also reframes the cut close as a DISCIPLINE WIN:
The chicken-and-egg-closure milestone IS achieved (reusable #16 fix works); the next-layer bug just becomes visible. That's the observability-pattern operating end-to-end across two layers in one cut cycle.
— QM, 2026-06-24, post-Surveyor e455 disposition refinement.
workflow_runsAPI can report success without actual job execution (trusted-proxy trap) #47