Skip to content

fix(tag-release): push the tag with git instead of gh --target - #193

Merged
stozo04 merged 1 commit into
mainfrom
fix/tag-push-then-release
Sep 8, 2026
Merged

stozo04 merged 1 commit into
mainfrom
fix/tag-push-then-release

Conversation

@stozo04

@stozo04 stozo04 commented Sep 8, 2026

Copy link
Copy Markdown
Owner

Root cause of the three failed tag.yml runs, and it isn't this repo's configuration.

cli/cli#9514: gh release create <tag> --target <sha> returns HTTP 403 for GitHub Actions tokens and fine-grained PATs even with contents: write or write-all, while the identical command succeeds under personal auth. Dropping --target makes it work.

Every piece of evidence lines up:

observation fits
PAT refused: "not accessible by personal access token"
GITHUB_TOKEN refused: "not accessible by integration"
Run log showed Contents: write granted ✔ — permissions were never the problem
No tag ruleset; protected tags deprecated and empty ✔ — nothing repo-side was blocking
Same command succeeded from Steven's machine ✔ — personal auth is unaffected

It stayed hidden until now because 1.0.49–1.0.51 were all tagged by hand. The bug is only reachable by a token, and no token had ever cut a tag here before this week.

The fix

Create and push the tag with git, then create the release against the tag that now exists — no --target. Plain git push of a tag ref isn't affected by the bug. The end state is identical.

Resumability, which the new order made necessary

The tag now lands before the release, so a failure between the two leaves a pushed tag with nothing attached — and the old "tag already exists" check would have refused that state forever. Now:

  • tag exists at the same sha, no release → resume and create the release
  • tag exists at the same sha with a release → "already released, nothing to do"
  • tag exists at a different sha → still a hard stop, because that tag asserts something else shipped

1.0.52

Already tagged and released from Steven's machine at 14:51, and live on Play. This changes nothing about it — it's for 1.0.53 onward. Both final checks pass: openloop-1.0.52-52.aab was confirmed present and jar verified during the tag run, and the release resolves at 1.0.52.

🤖 Generated with Claude Code

https://claude.ai/code/session_01Miqsf1M14nY5TKiZHzyjNY


Note

Low Risk
Release automation script only; behavior is more resilient for CI tokens and idempotent re-runs after partial failure.

Overview
Fixes failed automated release tagging in CI by stopping use of gh release create --target <sha>, which returns HTTP 403 for GitHub Actions and fine-grained PATs despite contents: write (cli/cli#9514).

The script now creates and pushes the version tag with git, then runs gh release create against that tag (no --target). Docs in the script header explain why.

Because the tag is pushed before the GitHub release, a partial failure can leave a tag with no release. The “tag already exists” logic is updated: same SHA and no release → resume and create the release; same SHA with release → exit; different SHA → still a hard error. gh release create failures now tell you the tag is already on the remote and to re-run the script.

Reviewed by Cursor Bugbot for commit 5f5cc28. Bugbot is set up for automated code reviews on this repo. Configure here.

`gh release create --target <sha>` returns HTTP 403 "Resource not accessible
by integration" (or "...by personal access token") for GitHub Actions tokens
and fine-grained PATs even when contents: write is granted — cli/cli#9514.
The same command succeeds under personal auth, which is why this only showed
up once the release moved into a workflow: 1.0.49 through 1.0.51 were tagged
from the owner's machine.

Create and push the tag with git, then create the release against the tag
that now exists, with no --target. Plain git push is not affected, and the
result is identical: an annotated ref at the verified sha with a release
attached.

Re-running after a partial failure is now handled explicitly. The tag lands
before the release, so a failure between the two used to leave a state the
old "tag already exists" check would refuse forever. A tag at the SAME sha
with no release is now recognized as resumable; a tag at a different sha is
still a hard stop.
@stozo04
stozo04 merged commit 2295f69 into main Sep 8, 2026
3 checks passed
@stozo04
stozo04 deleted the fix/tag-push-then-release branch September 8, 2026 14:55

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 2 potential issues.

Fix All in Cursor

Bugbot Autofix is ON, but it could not run because the branch was deleted or merged before autofix could start.

Reviewed by Cursor Bugbot for commit 5f5cc28. Configure here.

Comment thread scripts/tag-release.ps1
if ($taggedSha -ne $Sha) {
Write-Error "Tag $Version already exists and points at $taggedSha, not $Sha. Bump the version or delete the stale tag first."
exit 1
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Resume rejects equivalent commit SHAs

Medium Severity

The new resume check compares the existing tag's commit from git rev-list to -Sha as raw strings. git rev-list always prints a full hash, so an abbreviated -Sha that every earlier git check already accepted looks like a different commit and aborts the resume.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 5f5cc28. Configure here.

Comment thread scripts/tag-release.ps1
if ($LASTEXITCODE -ne 0) { Write-Error "Could not create the tag $Version locally."; exit 1 }
git push origin "refs/tags/$Version"
if ($LASTEXITCODE -ne 0) { Write-Error "Could not push the tag $Version. The local tag remains; delete it with ``git tag -d $Version`` if you are not retrying."; exit 1 }
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Retry skips pushing a local-only tag

Medium Severity

When a local tag already exists at -Sha, the script skips git push and treats that tag as already published. A leftover local tag after a failed push is not on origin, so gh release create without --target has no remote tag to attach to.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 5f5cc28. Configure here.

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