Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 22 additions & 10 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
name: Move major tag

# 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:
push:
tags:
- 'v*'
release:
types: [published, released]

# 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
Expand All @@ -25,12 +31,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
Expand All @@ -39,9 +51,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]*)$" \
Expand Down