workflows: _release-draft.yml@v0.2.0 fails on prep-PR merge; needs diagnostic #16

Closed
opened 2026-06-24 19:11:40 +02:00 by quartermaster · 4 comments

Symptom

When PR #15 (chore(release): v0.2.1 prep PR) was merged to main, the consumer-shape release-draft.yml autonomously fired (correct — the if: gate matched release-prep/v0.2.1 head ref) + called _release-draft.yml@v0.2.0. The reusable workflow failed (tasks 12863 + 12864). Same shape happened earlier on PR #13's close (tasks 12857 + 12858).

Empirical state

  • Tasks 12863 (draft outer step) + 12864 (create Forgejo draft release job) → both failure
  • Forgejo runner log shows task 12863 picked up at 2026-06-24T17:08:37Z, no further output → suggests the failure happened inside the workflow, not at scheduling
  • No easily-accessible log content via API; would need to inspect Forgejo's task-log surface directly

Workaround used for v0.2.1 cut

Ran scripts/draft-release.sh --version 0.2.1 locally — draft created cleanly as id=111. Operator publishes manually. v0.2.1 ships; the dogfood-via-workflow path is broken for release-draft specifically.

Investigation needed

What changed between local invocation and CI invocation:

  • Local: FORGEJO_TOKEN=$FORGEJO_TOKEN_QUARTERMASTER + script runs from current dir
  • CI: FORGEJO_TOKEN=${{ secrets.GITHUB_TOKEN }} + script runs from .release-toolkit/scripts/ (checked out at v0.2.0)

Hypotheses (ranked by likelihood):

  1. GITHUB_TOKEN permission insufficientsecrets.GITHUB_TOKEN may lack contents: write scope needed for the Forgejo /releases POST. The reusable's permissions: block lists contents: write but maybe Forgejo's auto-injected token doesn't honor that on pull_request: closed events
  2. The pull_request event's GITHUB_TOKEN scope — Forgejo Actions may have a tighter scope for tokens injected on PR-merge-triggered workflows than workflow_dispatch ones
  3. actions/checkout@v4 failure — the JS-based action may have a Forgejo-specific issue when the consumer is frankenbit/release-toolkit itself (toolkit-on-toolkit case)
  4. The --config release-toolkit.yml pathrelease-toolkit.yml exists at repo root + has correct content; unlikely to be the cause

Disposition lean

(A) Reproduce + diagnose: trigger release-draft.yml manually via workflow_dispatch (which IS supported in the consumer wrapper) with tag: v0.2.1 → captures the failure path with operator visibility. Then read the actual error from the Forgejo Actions UI.

(B) If GITHUB_TOKEN scope is the issue: change _release-draft.yml to accept a token input from the consumer + the consumer can pass an explicit token from secrets — but that defeats the cleanness of the auto-flow.

(C) v0.2.x release: ship the fix in v0.2.2 once diagnosed.

Cross-tracker

  • Worked instance: today's v0.2.1 cut hit this on autonomous draft-release-on-prep-PR-merge
  • Sibling: release-toolkit#14 (chore vs feat docs) — both are dogfood-arc surfacing
  • v0.2.1 still ships (manual draft creation); this is forward-fix territory

— QM, 2026-06-24, surfaced during v0.2.1 dogfood cut close.

## Symptom When PR #15 (`chore(release): v0.2.1` prep PR) was merged to main, the consumer-shape `release-draft.yml` autonomously fired (correct — the `if:` gate matched `release-prep/v0.2.1` head ref) + called `_release-draft.yml@v0.2.0`. The reusable workflow **failed** (tasks 12863 + 12864). Same shape happened earlier on PR #13's close (tasks 12857 + 12858). ## Empirical state - Tasks 12863 (`draft` outer step) + 12864 (`create Forgejo draft release` job) → both `failure` - Forgejo runner log shows task 12863 picked up at 2026-06-24T17:08:37Z, no further output → suggests the failure happened inside the workflow, not at scheduling - No easily-accessible log content via API; would need to inspect Forgejo's task-log surface directly ## Workaround used for v0.2.1 cut Ran `scripts/draft-release.sh --version 0.2.1` locally — draft created cleanly as id=111. Operator publishes manually. v0.2.1 ships; the dogfood-via-workflow path is broken for release-draft specifically. ## Investigation needed What changed between local invocation and CI invocation: - Local: `FORGEJO_TOKEN=$FORGEJO_TOKEN_QUARTERMASTER` + script runs from current dir - CI: `FORGEJO_TOKEN=${{ secrets.GITHUB_TOKEN }}` + script runs from `.release-toolkit/scripts/` (checked out at v0.2.0) Hypotheses (ranked by likelihood): 1. **GITHUB_TOKEN permission insufficient** — `secrets.GITHUB_TOKEN` may lack `contents: write` scope needed for the Forgejo `/releases` POST. The reusable's `permissions:` block lists `contents: write` but maybe Forgejo's auto-injected token doesn't honor that on `pull_request: closed` events 2. **The pull_request event's GITHUB_TOKEN scope** — Forgejo Actions may have a tighter scope for tokens injected on PR-merge-triggered workflows than workflow_dispatch ones 3. **actions/checkout@v4 failure** — the JS-based action may have a Forgejo-specific issue when the consumer is `frankenbit/release-toolkit` itself (toolkit-on-toolkit case) 4. **The `--config release-toolkit.yml` path** — `release-toolkit.yml` exists at repo root + has correct content; unlikely to be the cause ## Disposition lean (A) Reproduce + diagnose: trigger `release-draft.yml` manually via workflow_dispatch (which IS supported in the consumer wrapper) with `tag: v0.2.1` → captures the failure path with operator visibility. Then read the actual error from the Forgejo Actions UI. (B) If GITHUB_TOKEN scope is the issue: change `_release-draft.yml` to accept a token input from the consumer + the consumer can pass an explicit token from secrets — but that defeats the cleanness of the auto-flow. (C) v0.2.x release: ship the fix in v0.2.2 once diagnosed. ## Cross-tracker - Worked instance: today's v0.2.1 cut hit this on autonomous draft-release-on-prep-PR-merge - Sibling: release-toolkit#14 (chore vs feat docs) — both are dogfood-arc surfacing - v0.2.1 still ships (manual draft creation); this is forward-fix territory — QM, 2026-06-24, surfaced during v0.2.1 dogfood cut close.
Author
Owner

n=3 worked instance: v0.3.0 cut hit the same failure (2026-06-24 20:48)

Recurrence on PR #25 (chore(release): v0.3.0) merge: the autonomous release-draft.yml fired correctly (the if: gate matched release-prep/v0.3.0 head ref) + called _release-draft.yml@v0.2.0. Failed identically to the v0.2.1 instances (tasks 12863 + 12864).

Workaround used for v0.3.0 cut: ran scripts/draft-release.sh --version 0.3.0 locally — draft id=112 created cleanly at target ff328f69 (PR #25 merge head). Operator clicked Publish; tag v0.3.0 published 2026-06-24T20:52:51+02:00.

Recurrence count: n=3 worked instances now, all today:

  • v0.2.1 cut: PR #13 close (cancelled prep) — tasks 12857 + 12858 failure
  • v0.2.1 cut: PR #15 close (re-dispatched prep) — tasks 12863 + 12864 failure
  • v0.3.0 cut: PR #25 close — same shape

The autonomous draft path has now failed every single time it's fired. Priority worth bumping — the manual fallback works but defeats the dogfood. Worth diagnosing via the disposition (A) workflow_dispatch path before the next minor cut, since v0.3.x patches are the natural place to ship the fix.

— QM, 2026-06-24, v0.3.0 cut close.

## n=3 worked instance: v0.3.0 cut hit the same failure (2026-06-24 20:48) Recurrence on PR #25 (`chore(release): v0.3.0`) merge: the autonomous `release-draft.yml` fired correctly (the `if:` gate matched `release-prep/v0.3.0` head ref) + called `_release-draft.yml@v0.2.0`. Failed identically to the v0.2.1 instances (tasks 12863 + 12864). **Workaround used for v0.3.0 cut**: ran `scripts/draft-release.sh --version 0.3.0` locally — draft id=112 created cleanly at target ff328f69 (PR #25 merge head). Operator clicked Publish; tag v0.3.0 published 2026-06-24T20:52:51+02:00. **Recurrence count**: n=3 worked instances now, all today: - v0.2.1 cut: PR #13 close (cancelled prep) — tasks 12857 + 12858 failure - v0.2.1 cut: PR #15 close (re-dispatched prep) — tasks 12863 + 12864 failure - v0.3.0 cut: PR #25 close — same shape The autonomous draft path has now failed every single time it's fired. **Priority worth bumping** — the manual fallback works but defeats the dogfood. Worth diagnosing via the disposition (A) workflow_dispatch path before the next minor cut, since v0.3.x patches are the natural place to ship the fix. — QM, 2026-06-24, v0.3.0 cut close.
Author
Owner

Root cause identified (v0.3.1 sprint diagnostic, n=2 confirmed)

Probed the actual task logs at /srv/docker/forgejo/data/gitea/actions_log/frankenbit/release-toolkit/ (Forgejo public API doesn't expose Actions task logs — observability gap orthogonal to this issue).

Empirical pattern across both task 12863 (v0.2.1 autonomous on PR #15 close) AND task 12899 (manual workflow_dispatch v0.3.0 just fired)

Both runs show IDENTICAL skip:

... checkout consumer ✓        → main HEAD = ff328f6 (PR #25 merge) [for 12899]
... checkout release-toolkit ✓ → refs/tags/v0.2.0 = a521998
::remove-matcher owner=checkout-git::
[400ms gap with NO output]
[draft-release] --version is required          ← run-draft-release.sh step starts
Usage: draft-release.sh --version VER [OPTIONS]
exitcode '1': failure

The install deps + normalize version steps DO NOT EXECUTE. No ::set-output:: marker, no yq 3.4.3 from command -v yq, no echo "version=0.3.0". The runner jumps from step 2 (checkout release-toolkit) straight to step 5 (run draft-release.sh), skipping steps 3 + 4.

Since normalize version never runs, steps.version.outputs.version evaluates to empty string. The expression --version "${{ steps.version.outputs.version }}" resolves to --version "". The script's argument parser hits the empty value, treats --version as missing, exits 1.

Comparative probe

The successful release-prep reusable (task 12891) ran on the SAME v0.2.0 reusable shape + the SAME runner image (forgejo-ci-go:latest) — its log shows yq 3.4.3 + ::set-output:: markers normally. So the runner CAN execute multi-step run: blocks correctly elsewhere. The skip is specific to the _release-draft.yml@v0.2.0 step sequence.

Suspected: act_runner / Forgejo Actions has a step-ordering bug specific to the v0.2.0 release-draft reusable's structure — likely the id: version + env: combination on the normalize-version step or some other YAML-shape quirk that causes parser-level drop. (Not yet root-caused at the runner-software level; the symptom-level fix below sidesteps it.)

Disposition for v0.3.1 fix

(A) Inline-collapse normalize version into the run draft-release.sh step. Eliminates the cross-step output dependency that's failing to propagate. Same logic, single step. Adds an empty-version guard with actionable error.

- name: run draft-release.sh
  shell: bash
  env:
    FORGEJO_TOKEN: ${{ secrets.GITHUB_TOKEN }}
    FORGEJO_BASE_URL: ${{ github.server_url }}
    RAW_VERSION: ${{ inputs.version }}
  run: |
    set -euo pipefail
    v="$RAW_VERSION"
    v="${v#release-prep/}"
    v="${v#v}"
    if [[ -z "$v" ]]; then
      echo "::error::normalize-version produced empty string from inputs.version='$RAW_VERSION'"
      exit 1
    fi
    .release-toolkit/scripts/draft-release.sh \
      --version "$v" \
      --config "${{ inputs.config_path }}"

Forward-cycle implication

The fix lands in v0.3.1. Existing consumers (cellblock, the toolkit ITSELF) reference @v0.2.0 in their consumer-side release-draft.yml. For the fix to take effect, consumers must bump their uses: ...@v0.2.0uses: ...@v0.3.1 after v0.3.1 ships. The toolkit's own consumer-side workflow gets that bump as part of v0.3.1 closing. cellblock + tmux-tell migrations would pick the bump up at adoption time (no urgent action needed).

This is the standard chicken-and-egg dynamic for self-hosting release substrate. Worth a one-liner note in the v0.3.1 CHANGELOG so consumers know.

Plan

  1. Open PR with the inline-collapse fix
  2. Same change in toolkit's OWN consumer-side release-draft.yml (bump @v0.2.0@v0.3.1 in the same PR? Or after v0.3.1 ships?)
  3. Surveyor review
  4. Ship in v0.3.1 cluster

Surfacing this comment before the PR opens so the diagnostic is captured even if I get pulled off mid-flight.

— Quartermaster, 2026-06-24 21:18, v0.3.1 sprint engagement post-sleep.

## Root cause identified (v0.3.1 sprint diagnostic, n=2 confirmed) Probed the actual task logs at `/srv/docker/forgejo/data/gitea/actions_log/frankenbit/release-toolkit/` (Forgejo public API doesn't expose Actions task logs — observability gap orthogonal to this issue). ### Empirical pattern across both task 12863 (v0.2.1 autonomous on PR #15 close) AND task 12899 (manual workflow_dispatch v0.3.0 just fired) Both runs show IDENTICAL skip: ``` ... checkout consumer ✓ → main HEAD = ff328f6 (PR #25 merge) [for 12899] ... checkout release-toolkit ✓ → refs/tags/v0.2.0 = a521998 ::remove-matcher owner=checkout-git:: [400ms gap with NO output] [draft-release] --version is required ← run-draft-release.sh step starts Usage: draft-release.sh --version VER [OPTIONS] exitcode '1': failure ``` **The `install deps` + `normalize version` steps DO NOT EXECUTE.** No `::set-output::` marker, no `yq 3.4.3` from `command -v yq`, no `echo "version=0.3.0"`. The runner jumps from step 2 (checkout release-toolkit) straight to step 5 (run draft-release.sh), skipping steps 3 + 4. Since `normalize version` never runs, `steps.version.outputs.version` evaluates to empty string. The expression `--version "${{ steps.version.outputs.version }}"` resolves to `--version ""`. The script's argument parser hits the empty value, treats `--version` as missing, exits 1. ### Comparative probe The successful `release-prep` reusable (task 12891) ran on the SAME v0.2.0 reusable shape + the SAME runner image (`forgejo-ci-go:latest`) — its log shows `yq 3.4.3` + `::set-output::` markers normally. So the runner CAN execute multi-step `run:` blocks correctly elsewhere. The skip is specific to the `_release-draft.yml@v0.2.0` step sequence. Suspected: act_runner / Forgejo Actions has a step-ordering bug specific to the v0.2.0 release-draft reusable's structure — likely the `id: version` + `env:` combination on the normalize-version step or some other YAML-shape quirk that causes parser-level drop. (Not yet root-caused at the runner-software level; the symptom-level fix below sidesteps it.) ### Disposition for v0.3.1 fix (A) **Inline-collapse `normalize version` into the `run draft-release.sh` step.** Eliminates the cross-step output dependency that's failing to propagate. Same logic, single step. Adds an empty-version guard with actionable error. ```yaml - name: run draft-release.sh shell: bash env: FORGEJO_TOKEN: ${{ secrets.GITHUB_TOKEN }} FORGEJO_BASE_URL: ${{ github.server_url }} RAW_VERSION: ${{ inputs.version }} run: | set -euo pipefail v="$RAW_VERSION" v="${v#release-prep/}" v="${v#v}" if [[ -z "$v" ]]; then echo "::error::normalize-version produced empty string from inputs.version='$RAW_VERSION'" exit 1 fi .release-toolkit/scripts/draft-release.sh \ --version "$v" \ --config "${{ inputs.config_path }}" ``` ### Forward-cycle implication The fix lands in v0.3.1. Existing consumers (cellblock, the toolkit ITSELF) reference `@v0.2.0` in their consumer-side `release-draft.yml`. **For the fix to take effect, consumers must bump their `uses: ...@v0.2.0` → `uses: ...@v0.3.1` after v0.3.1 ships.** The toolkit's own consumer-side workflow gets that bump as part of v0.3.1 closing. cellblock + tmux-tell migrations would pick the bump up at adoption time (no urgent action needed). This is the standard chicken-and-egg dynamic for self-hosting release substrate. Worth a one-liner note in the v0.3.1 CHANGELOG so consumers know. ### Plan 1. Open PR with the inline-collapse fix 2. Same change in toolkit's OWN consumer-side `release-draft.yml` (bump `@v0.2.0` → `@v0.3.1` in the same PR? Or after v0.3.1 ships?) 3. Surveyor review 4. Ship in v0.3.1 cluster Surfacing this comment before the PR opens so the diagnostic is captured even if I get pulled off mid-flight. — Quartermaster, 2026-06-24 21:18, v0.3.1 sprint engagement post-sleep.
Author
Owner

Diagnostic refinement — install-deps run-state is AMBIGUOUS from log

Surveyor cac0 surfaced a sharp catch on the prior comment's over-statement: I claimed "BOTH install deps AND normalize version DO NOT EXECUTE" based on the 400ms gap with no visible output. Filed-rootcause-is-hypothesis discipline applies — that asserted certainty on two distinct steps without proving the install-deps half.

Canonical-probe just done

install-deps body has this structure:

for tool in yq jq curl; do
  command -v "$tool" >/dev/null || missing+=("$tool")
done
if (( ${#missing[@]} > 0 )); then
  # apt-get update + install ...
fi
  • command -v "$tool" >/dev/null produces zero output by design (redirected)
  • If missing=() empty (pre-baked image), the if-block doesn't fire — zero output
  • The toolkit's forgejo-ci-go:latest image has yq + jq + curl pre-baked

So a silently-running install-deps with pre-baked deps looks identical in the log to a skipped install-deps step. The 400ms gap is the same either way.

What the canonical evidence DOES support:

  • checkout release-toolkit ran (visible HEAD probe + matcher removal)
  • normalize version DID NOT execute (no ::set-output:: marker — if it had run, that marker would be visible per the comparative probe of successful task 12891)
  • ? install deps state — ambiguous (no log output either way for pre-baked deps; can't distinguish run-silently-no-op from skipped)
  • run draft-release.sh ran (visible script invocation + error)

Implications for the v0.3.1 fix (PR #26)

The fix correctly addresses the confirmed normalize-version skip (inline-collapse sidesteps the cross-step output dependency that's failing). For pre-baked-deps consumers (toolkit-on-toolkit + any consumer using forgejo-ci-go:latest), the install-deps ambiguity doesn't bite — both branches produce a no-op.

For external consumers without pre-baked yq/jq/curl, this is forward open: if install-deps was genuinely skipped, they'd hit yq: command not found from inside draft-release.sh at YAML-parse time. That would surface as a DIFFERENT failure shape (not "--version is required"), which we haven't seen yet because no external consumer has cut a release through the broken workflow.

Disposition forward:

  • Keep PR #26 as-is (narrow scope: fixes the confirmed normalize-version skip)
  • Don't pre-emptively inline install-deps until/unless an external consumer hits it
  • Add an observability fix: a one-line echo "[install-deps] checked yq=$YQ_OK jq=$JQ_OK curl=$CURL_OK" (or similar) so the install-deps run-state is visible in future logs, removing the ambiguity. Filing as separate follow-up tracker rather than scope-creeping PR #26.

Discipline note (banking)

This is the filed-rootcause-is-hypothesis pattern playing out: my n=2 confirmed observation ("install-deps + normalize-version produce no log output") got wrapped in a stronger claim ("both DO NOT execute") that conflated "no observable output" with "confirmed skip." Surveyor's catch is the same shape as the per-discipline-pin promotion-threshold catches throughout this sprint — independent verification surfacing where my own diagnostic ran past the evidence.

— Quartermaster, 2026-06-24 21:32, post-Surveyor cac0 catch on PR #26.

## Diagnostic refinement — install-deps run-state is AMBIGUOUS from log Surveyor cac0 surfaced a sharp catch on the prior comment's over-statement: I claimed "BOTH `install deps` AND `normalize version` DO NOT EXECUTE" based on the 400ms gap with no visible output. Filed-rootcause-is-hypothesis discipline applies — that asserted certainty on two distinct steps without proving the install-deps half. ### Canonical-probe just done `install-deps` body has this structure: ```bash for tool in yq jq curl; do command -v "$tool" >/dev/null || missing+=("$tool") done if (( ${#missing[@]} > 0 )); then # apt-get update + install ... fi ``` - `command -v "$tool" >/dev/null` produces **zero output by design** (redirected) - If `missing=()` empty (pre-baked image), the if-block doesn't fire — **zero output** - The toolkit's `forgejo-ci-go:latest` image has yq + jq + curl pre-baked So a silently-running install-deps with pre-baked deps looks **identical** in the log to a skipped install-deps step. The 400ms gap is the same either way. What the canonical evidence DOES support: - ✓ `checkout release-toolkit` ran (visible HEAD probe + matcher removal) - ✗ `normalize version` DID NOT execute (no `::set-output::` marker — if it had run, that marker would be visible per the comparative probe of successful task 12891) - ? `install deps` state — **ambiguous** (no log output either way for pre-baked deps; can't distinguish run-silently-no-op from skipped) - ✓ `run draft-release.sh` ran (visible script invocation + error) ### Implications for the v0.3.1 fix (PR #26) The fix correctly addresses the **confirmed** normalize-version skip (inline-collapse sidesteps the cross-step output dependency that's failing). For pre-baked-deps consumers (toolkit-on-toolkit + any consumer using `forgejo-ci-go:latest`), the install-deps ambiguity doesn't bite — both branches produce a no-op. **For external consumers without pre-baked yq/jq/curl, this is forward open**: if install-deps was genuinely skipped, they'd hit `yq: command not found` from inside draft-release.sh at YAML-parse time. That would surface as a DIFFERENT failure shape (not "--version is required"), which we haven't seen yet because no external consumer has cut a release through the broken workflow. Disposition forward: - Keep PR #26 as-is (narrow scope: fixes the confirmed normalize-version skip) - Don't pre-emptively inline install-deps until/unless an external consumer hits it - **Add an observability fix**: a one-line `echo "[install-deps] checked yq=$YQ_OK jq=$JQ_OK curl=$CURL_OK"` (or similar) so the install-deps run-state is visible in future logs, removing the ambiguity. Filing as separate follow-up tracker rather than scope-creeping PR #26. ### Discipline note (banking) This is the **filed-rootcause-is-hypothesis** pattern playing out: my n=2 confirmed observation ("install-deps + normalize-version produce no log output") got wrapped in a stronger claim ("both DO NOT execute") that conflated "no observable output" with "confirmed skip." Surveyor's catch is the same shape as the per-discipline-pin promotion-threshold catches throughout this sprint — independent verification surfacing where my own diagnostic ran past the evidence. — Quartermaster, 2026-06-24 21:32, post-Surveyor cac0 catch on PR #26.
Author
Owner

AC tick (post-merge catchup)

Shipped via PR #26 (commit 7a1cb7c). Diagnostic refined via comments 73402 + 73426 (Surveyor cac0 catch on over-stated install-deps claim).

Disposition (A) ACs

  • Reproduced via workflow_dispatch — task 12899 (manual release-draft.yml dispatch with tag: v0.3.0) hit identical failure to the n=3 autonomous instances (12863, 12864 + the v0.3.0 prep-PR-merge fire)
  • Root cause identified at the symptom levelnormalize version step DOES NOT execute (verified absent ::set-output:: marker per comparative probe of successful task 12891). steps.version.outputs.version evaluates to empty → script bails with --version is required.
  • Symptom-level fix landed — inline-collapse normalize-version into the run-draft-release.sh step (eliminates cross-step output dependency). PR #26 commit 7a1cb7c.
  • Empty-version guard added — actionable ::error:: if normalization ever produces empty (defensive against future regressions)

Deferred-conditional (surfaced during PR #26 review)

  • install-deps run-state ambiguity: original diagnostic over-stated certainty on "install-deps DOES NOT execute"; canonical-probe showed command -v "$tool" >/dev/null produces zero output by design → silently-running install-deps with pre-baked deps is indistinguishable from skipped install-deps in current log. Diagnostic refined in comment 73426; observability fix tracked as #29 (one-line echo "[install-deps] checked: yq, jq, curl" across all 4 reusables to disambiguate run-state in future logs).
  • act_runner root-cause at runtime layer: this fix sidesteps the symptom (step-skip) without root-causing the runtime behavior. Forward-watch — if the step-skip pattern surfaces in OTHER reusables, file upstream Forgejo Actions tracker. Not in this issue's scope.
  • Chicken-and-egg closure: the fix only takes effect when consumers bump uses: ...@v0.2.0uses: ...@v0.3.1. Toolkit's own consumer-side wrapper bump is queued for v0.3.2 sprint (closes the chicken-and-egg via dogfood). External consumers pick it up at adoption time.

Cross-tracker confirmation

  • Worked instance count: n=3 autonomous + n=1 manual reproduction confirmed during the diagnostic + fix cycle. All on 2026-06-24.
  • Sibling #14 (chore vs feat) — both shipped in v0.3.1 ✓
  • Forward sibling #29 (install-deps observability) — surfaced via this issue's PR review, filed for v0.3.x ✓

Closed via PR #26 merge. AC + deferred-conditional summary recorded.

— QM, 2026-06-24, v0.3.1 post-publish AC-tick pass.

## AC tick (post-merge catchup) Shipped via PR #26 (commit 7a1cb7c). Diagnostic refined via comments 73402 + 73426 (Surveyor cac0 catch on over-stated install-deps claim). ### Disposition (A) ACs - [x] **Reproduced via workflow_dispatch** — task 12899 (manual `release-draft.yml` dispatch with `tag: v0.3.0`) hit identical failure to the n=3 autonomous instances (12863, 12864 + the v0.3.0 prep-PR-merge fire) - [x] **Root cause identified at the symptom level** — `normalize version` step DOES NOT execute (verified absent `::set-output::` marker per comparative probe of successful task 12891). `steps.version.outputs.version` evaluates to empty → script bails with `--version is required`. - [x] **Symptom-level fix landed** — inline-collapse normalize-version into the run-draft-release.sh step (eliminates cross-step output dependency). PR #26 commit 7a1cb7c. - [x] **Empty-version guard added** — actionable `::error::` if normalization ever produces empty (defensive against future regressions) ### Deferred-conditional (surfaced during PR #26 review) - [x] *install-deps run-state ambiguity:* original diagnostic over-stated certainty on "install-deps DOES NOT execute"; canonical-probe showed `command -v "$tool" >/dev/null` produces zero output by design → silently-running install-deps with pre-baked deps is indistinguishable from skipped install-deps in current log. **Diagnostic refined in comment 73426**; observability fix tracked as **#29** (one-line `echo "[install-deps] checked: yq, jq, curl"` across all 4 reusables to disambiguate run-state in future logs). - [x] *act_runner root-cause at runtime layer:* this fix sidesteps the symptom (step-skip) without root-causing the runtime behavior. Forward-watch — if the step-skip pattern surfaces in OTHER reusables, file upstream Forgejo Actions tracker. Not in this issue's scope. - [ ] *Chicken-and-egg closure:* the fix only takes effect when consumers bump `uses: ...@v0.2.0` → `uses: ...@v0.3.1`. **Toolkit's own consumer-side wrapper bump is queued for v0.3.2 sprint** (closes the chicken-and-egg via dogfood). External consumers pick it up at adoption time. ### Cross-tracker confirmation - Worked instance count: n=3 autonomous + n=1 manual reproduction confirmed during the diagnostic + fix cycle. All on 2026-06-24. - Sibling #14 (chore vs feat) — both shipped in v0.3.1 ✓ - Forward sibling #29 (install-deps observability) — surfaced via this issue's PR review, filed for v0.3.x ✓ Closed via PR #26 merge. AC + deferred-conditional summary recorded. — QM, 2026-06-24, v0.3.1 post-publish AC-tick pass.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
frankenbit/release-toolkit#16
No description provided.