From b04919cb018f657bdf6599240cc2e096b9f1cb8d Mon Sep 17 00:00:00 2001 From: Project516 <138796702+Project516@users.noreply.github.com> Date: Wed, 26 Aug 2026 10:17:36 -0500 Subject: [PATCH 1/2] Trigger major-tag move on release publish, not tag push Tag pushes never raised a workflow run in this repo (issue #7): three tag pushes today, including a probe tag, produced zero runs of this workflow, while pushes to main triggered verify in the same session. Switch the trigger to release: published. A release is what actually happens when we cut one, and the event fires reliably. Pull the tag name from the release payload instead of the ref, and skip prereleases so a release candidate cannot move the major tag. The probe tag v0.0.1-triggertest is deleted from the remote as part of this cleanup; it was not a real release. --- .github/workflows/release.yml | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index c405161..67f41eb 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,12 +1,14 @@ name: Move major tag +# Tag pushes never reliably trigger a workflow run in this repo, so this +# listens for the release being published instead -- that always happens +# when we cut a release, and GitHub raises the event consistently. on: - push: - tags: - - 'v*' + release: + types: [published] -# One run at a time, so two tag pushes cannot both decide where a major tag -# belongs. Queued rather than cancelled: every push should get its turn. +# One run at a time, so two releases cannot both decide where a major tag +# belongs. Queued rather than cancelled: every release should get its turn. concurrency: group: move-major-tag cancel-in-progress: false @@ -25,12 +27,18 @@ jobs: - name: Move the major tag to the newest stable release in that major env: - TAG: ${{ github.ref_name }} + TAG: ${{ github.event.release.tag_name }} + PRERELEASE: ${{ github.event.release.prerelease }} run: | set -euo pipefail + if [[ "$PRERELEASE" == "true" ]]; then + echo "$TAG is marked as a prerelease; leaving the major tag alone" + exit 0 + fi + # Strict semver only: no leading zeroes, no pre-release suffix, so a - # v1.0.1-rc.1 push cannot put v1 on a release candidate. + # v1.0.1-rc.1 release cannot put v1 on a release candidate. if [[ ! "$TAG" =~ ^v(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)$ ]]; then echo "$TAG is not a stable vX.Y.Z tag; leaving the major tag alone" exit 0 @@ -39,9 +47,9 @@ jobs: MAJOR="v${BASH_REMATCH[1]}" # Point the major at the greatest stable tag in the series rather than - # at whatever tag triggered this run. Re-pushing an old tag would - # otherwise walk the major backward onto a version consumers have - # already moved off. + # at whatever tag triggered this run. Re-publishing an old release + # would otherwise walk the major backward onto a version consumers + # have already moved off. git fetch --force --tags origin NEWEST="$(git tag --list "${MAJOR}.*" \ | grep -E "^${MAJOR}\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)$" \ From 6f9dc5730f8a41706bc83b60e60e2a53ae3e68e5 Mon Sep 17 00:00:00 2001 From: Project516 <138796702+Project516@users.noreply.github.com> Date: Wed, 26 Aug 2026 10:30:52 -0500 Subject: [PATCH 2/2] Also trigger on the released event CodeRabbit flagged that published alone misses a prerelease being promoted to a full release: GitHub fires released for that transition, not published, and the prerelease guard only matters for a direct publish. Add released to the trigger types. A plain stable publish now fires both published and released, but the concurrency group serialises the two runs and the job always points the major tag at the greatest stable tag in the series rather than the triggering one, so the second run is a harmless no-op. --- .github/workflows/release.yml | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 67f41eb..7bf6467 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,11 +1,15 @@ name: Move major tag -# Tag pushes never reliably trigger a workflow run in this repo, so this -# listens for the release being published instead -- that always happens -# when we cut a release, and GitHub raises the event consistently. +# This listens for the release being published because tag pushes do not +# raise a workflow run in this repo. `released` is included alongside +# `published` because promoting a prerelease to a full release fires +# `released`, not `published`; a plain stable publish fires both, but the +# concurrency group serialises them and the job always points the major +# tag at the greatest stable tag in the series, so the second run is a +# harmless no-op. on: release: - types: [published] + types: [published, released] # One run at a time, so two releases cannot both decide where a major tag # belongs. Queued rather than cancelled: every release should get its turn.