From 825a91046c8b87a4bffec37c9d37860c24535834 Mon Sep 17 00:00:00 2001 From: Sergio Alexander Florez Galeano Date: Mon, 1 Jun 2026 13:58:44 -0500 Subject: [PATCH] ci(release): push main before tagging; bump checkout to v5 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two hardening changes to the auto-release job: 1. Push order. The step pushed the branch and tag together with `git push origin main --follow-tags`. git pushes each ref independently, so when the protected `main` push was rejected the tag had already been created on the remote — leaving a dangling `vX.Y.Z` tag pointing at a commit not reachable from main, which then blocks every future release (the tag "already exists"). Now we push `HEAD:main` first and only create+push the tag after main accepts the release commit, so a rejection leaves no tag behind. 2. Bump actions/checkout@v4 -> @v5 to run on Node 24 and clear the "Node.js 20 actions are deprecated" runner warning. Co-Authored-By: Claude Opus 4.8 (1M context) --- .github/workflows/auto-release.yml | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/.github/workflows/auto-release.yml b/.github/workflows/auto-release.yml index e640d3a..9fcd3e7 100644 --- a/.github/workflows/auto-release.yml +++ b/.github/workflows/auto-release.yml @@ -38,7 +38,7 @@ jobs: # Skip our own release commits to prevent an infinite loop. if: ${{ !startsWith(github.event.head_commit.message, 'chore(release):') }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 with: fetch-depth: 0 # Uses `AUTOMATION_GITHUB_TOKEN` (the org convention) so the bot @@ -168,8 +168,16 @@ jobs: run: | git add -A git commit -m "chore(release): ${NEW_VERSION} [skip ci]" + # Push the branch FIRST. If main is rejected (e.g. branch + # protection), we bail out here BEFORE creating/pushing the tag, so + # a failed run can never leave a dangling tag pointing at a commit + # that isn't reachable from main (which would block every future + # release with an "already exists" tag push). + git push origin HEAD:main + # main accepted the release commit — now tag that exact commit and + # push the tag on its own. git tag -a "$NEW_TAG" -m "Release ${NEW_VERSION}" - git push origin main --follow-tags + git push origin "refs/tags/${NEW_TAG}" - name: Create GitHub Release if: steps.version.outputs.skip != 'true'