Skip to content

Fix release automation: explicitly dispatch release.yml instead of relying on the tag push#51

Merged
smaniches merged 1 commit into
mainfrom
claude/repo-audit-improvement-cxu5a8
Jul 7, 2026
Merged

Fix release automation: explicitly dispatch release.yml instead of relying on the tag push#51
smaniches merged 1 commit into
mainfrom
claude/repo-audit-improvement-cxu5a8

Conversation

@smaniches

@smaniches smaniches commented Jul 6, 2026

Copy link
Copy Markdown
Owner

The bug, confirmed on the actual #50 merge

auto-tag-release.yml pushed the release tag using the workflow's own default GITHUB_TOKEN and assumed that push would trigger release.yml's push.tags listener, the way a manual git tag && git push would. It does not: GitHub suppresses push-triggered workflow runs caused by a GITHUB_TOKEN-authored push, specifically to prevent workflows from recursively triggering each other.

Confirmed directly: auto-tag-release.yml ran successfully on the #50 merge and pushed v0.1.0.dev4, but no release.yml run was ever created for that tag, no GitHub Release exists for it (404), and PyPI is still at 0.1.0.dev2. My mistake — I used this exact GitHub behavior to argue the two-workflow split was safe from double-firing, without working through that it also means the second workflow never fires at all.

The fix

  • auto-tag-release.yml: after pushing the tag, explicitly dispatches release.yml via gh workflow run (workflow_dispatch is the documented exception to the push-suppression above), passing the tag as both the dispatch ref and the ref input, plus a new create_github_release: true. Gains an actions: write permission to make that call.
  • release.yml: gains a create_github_release workflow_dispatch input (default false, preserving the existing "republish an already-released tag to PyPI only" behavior for a plain manual dispatch).
    • sign-and-release now runs on a real tag push or create_github_release == 'true', instead of only on a tag push.
    • The release step sets tag_name explicitly rather than relying on ref inference, so it's correct for both trigger types.
    • The PyPI publish step sets skip-existing: true, so a re-dispatch or an out-of-band manual republish of an already-published version doesn't fail the job.
    • push.tags and the existing ref-only manual-republish path are otherwise unchanged — a human pushing a tag with their own credentials isn't subject to the GITHUB_TOKEN suppression, so that path still works exactly as before.
  • CHANGELOG.md / CONTRIBUTING.md: corrected to state the real trigger mechanism instead of the false "the tag push triggers release.yml" claim.

Verification

  • Both workflow files parse as valid YAML with the expected jobs and workflow_dispatch inputs.
  • The embedded shell script's syntax checked with bash -n.
  • Full local gate unaffected (101 tests at 100% coverage, ruff, black, mypy --strict, bandit, pre-commit) — none of this touches groupoid/ or tests/.

Recovery for the still-unreleased v0.1.0.dev4

Once this merges, release.yml can be dispatched directly against the existing tag with ref=v0.1.0.dev4 and create_github_release=true, publishing the version that's been sitting tagged but unreleased since #50 merged — without deleting or recreating that tag. I can run that dispatch once this PR is merged, if you'd like.

…he tag push

auto-tag-release.yml (added in 0.1.0.dev4, #50) pushed the release tag
using the workflow's own default GITHUB_TOKEN and assumed that push
would trigger release.yml's push.tags listener, the way a manual
git tag && git push would. It does not: GitHub suppresses push-triggered
workflow runs caused by a GITHUB_TOKEN-authored push, specifically to
prevent workflows from recursively triggering each other. Confirmed on
the actual merge of #50: auto-tag-release.yml ran successfully and
pushed v0.1.0.dev4, but no release.yml run was ever created for that
tag, no GitHub Release exists for it, and PyPI stayed at 0.1.0.dev2.

auto-tag-release.yml now explicitly dispatches release.yml via
`gh workflow run` after pushing the tag (workflow_dispatch is the
documented exception to the push-suppression above), passing the tag as
both the dispatch ref and the ref input, plus a new create_github_release
input. The job gains an actions:write permission to make that dispatch
call.

release.yml gains the create_github_release workflow_dispatch input
(default false, preserving the existing "republish an already-released
tag to PyPI only" behavior for a plain manual dispatch) and:
- sign-and-release now runs on a real tag push OR
  create_github_release == 'true', instead of only on a tag push
- the release step sets tag_name explicitly rather than relying on ref
  inference, so it is correct for both a tag push and a workflow_dispatch
  run
- the PyPI publish step sets skip-existing: true, so a re-dispatch or an
  out-of-band manual republish of an already-published version does not
  fail the job

release.yml's push.tags trigger and its existing workflow_dispatch
"ref"-only republish path are otherwise unchanged: a human pushing a tag
with their own credentials is not subject to the GITHUB_TOKEN
suppression, so that path continues to work exactly as before.

CHANGELOG.md and CONTRIBUTING.md are corrected to state the real trigger
mechanism instead of the false "the tag push triggers release.yml"
claim.

Verified: both workflow files parse as valid YAML with the expected
jobs and workflow_dispatch inputs; the embedded shell script's syntax
checked with bash -n; the full local gate (pytest at 100% coverage,
ruff, black, mypy --strict, bandit, pre-commit) is unaffected, since
none of this touches groupoid/ or tests/.

Recovery for the still-unreleased v0.1.0.dev4: once this is merged,
release.yml can be dispatched directly against the existing tag with
ref=v0.1.0.dev4 and create_github_release=true, publishing the version
that has been sitting tagged but unreleased since #50 merged -- without
deleting or recreating that tag.
@smaniches smaniches marked this pull request as ready for review July 6, 2026 22:28
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@smaniches smaniches merged commit 6bf446a into main Jul 7, 2026
11 checks passed
@smaniches smaniches deleted the claude/repo-audit-improvement-cxu5a8 branch July 7, 2026 00:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants