Skip to content

ci: self-heal a missing GitHub Release in auto-release#11

Merged
REPPL merged 2 commits into
mainfrom
ci/v0.8.0-auto-release-hardening
Jul 8, 2026
Merged

ci: self-heal a missing GitHub Release in auto-release#11
REPPL merged 2 commits into
mainfrom
ci/v0.8.0-auto-release-hardening

Conversation

@REPPL

@REPPL REPPL commented Jul 8, 2026

Copy link
Copy Markdown
Owner

What

auto-release's detect previously set should_release=true only when the git
tag was absent, so a transient CI failure that created the tag but not the
GitHub Release left the version permanently un-released — the known operational
limit noted in #9.

This splits should_release into need_tag (tag absent) and need_release (tag
absent or the tag's GitHub Release absent):

  • the tag job runs on need_tag (so it never tries to recreate an existing tag);
  • the release job runs on need_release, guarded by !cancelled() and the
    tag job's result, so a skipped tag still releases (the re-release path)
    while a failed or cancelled one does not (a half-made tag never ships).

The re-release builds from the tagged commit, never the moved-on main HEAD:
detect resolves the tag to its immutable commit SHA and passes it to
release.yml via a new optional ref input (both checkout steps fall back to
inputs.ref || github.sha), preserving the anti-tag-move property — a resolved
commit SHA cannot be re-pointed. gh release view runs under the existing
contents: read with GH_TOKEN; the existence check fails open, backstopped by
gh release create's no-clobber default.

Review

Reviewed for security (token model / least privilege, injection posture,
anti-tag-move preservation, fail-open blast radius) and correctness (all four
detect outcomes against the release guard, the empty-ref fallback on both
release.yml entry points, output plumbing, idempotency). No blocking findings.

Assisted-by: Claude:claude-opus-4-8

REPPL added 2 commits July 8, 2026 18:35
detect only re-released when the git tag was absent, so a transient failure that
created the tag but not the GitHub Release wedged the version permanently. Split
should_release into need_tag (tag absent) and need_release (tag absent OR Release
absent): the tag job runs on need_tag, the release job on need_release guarded by
!cancelled() plus the tag job's result, so a skipped tag still releases and a
failed or cancelled one does not.

The re-release must build from the tagged commit, not the moved-on main HEAD:
detect resolves the tag to its immutable commit SHA and hands it to release.yml
via a new optional ref input (both checkouts fall back to inputs.ref ||
github.sha), preserving the anti-tag-move property. gh release view runs under
contents: read with GH_TOKEN; the existence check fails open, backstopped by
gh release create's no-clobber default.
@REPPL REPPL merged commit 2caa539 into main Jul 8, 2026
11 checks passed
@REPPL REPPL deleted the ci/v0.8.0-auto-release-hardening branch July 8, 2026 18:08
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.

1 participant