From 737e005e9d13e5bc4a0220b1ecac8e17e746d177 Mon Sep 17 00:00:00 2001 From: Jonah Lawrence Date: Thu, 17 Sep 2026 13:16:57 +0300 Subject: [PATCH 1/6] chore: Add workflow to update major version tag on release --- .../workflows/update-major-version-tag.yml | 65 +++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 .github/workflows/update-major-version-tag.yml diff --git a/.github/workflows/update-major-version-tag.yml b/.github/workflows/update-major-version-tag.yml new file mode 100644 index 00000000..01ec3b25 --- /dev/null +++ b/.github/workflows/update-major-version-tag.yml @@ -0,0 +1,65 @@ +name: Update Major Version Tag + +# Runs whenever a release is published (including "pre-release" if you want that too — +# adjust the `if` condition below to change scope). +on: + release: + types: [published] + +permissions: + contents: write + +jobs: + update-major-tag: + runs-on: ubuntu-latest + # Skip draft releases just in case; published releases won't normally be drafts, + # but this guards against workflow_dispatch/manual re-runs on stale events. + if: ${{ !github.event.release.draft }} + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Determine major version tag + id: major + run: | + tag="${{ github.event.release.tag_name }}" + + # Expect semver-ish tags like v1.2.3 or 1.2.3 + if [[ "$tag" =~ ^v?([0-9]+)\.[0-9]+\.[0-9]+(-.*)?$ ]]; then + major_num="${BASH_REMATCH[1]}" + else + echo "::error::Tag '$tag' does not look like a semver tag (vX.Y.Z). Skipping." + exit 1 + fi + + # Preserve the "v" prefix convention if the release tag used one. + if [[ "$tag" == v* ]]; then + major_tag="v${major_num}" + else + major_tag="${major_num}" + fi + + echo "major_tag=${major_tag}" >> "$GITHUB_OUTPUT" + echo "Resolved major tag: ${major_tag} (from release tag ${tag})" + + - name: Configure git + run: | + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + + - name: Move (or create) major version tag + env: + MAJOR_TAG: ${{ steps.major.outputs.major_tag }} + RELEASE_SHA: ${{ github.event.release.target_commitish }} + run: | + # target_commitish is usually a branch name for tags created via the UI/API, + # so resolve it to the actual commit the release's tag points at instead. + release_tag="${{ github.event.release.tag_name }}" + commit_sha="$(git rev-list -n 1 "$release_tag")" + + echo "Pointing ${MAJOR_TAG} at ${commit_sha} (release ${release_tag})" + + git tag -fa "$MAJOR_TAG" "$commit_sha" -m "Update ${MAJOR_TAG} to ${release_tag}" + git push origin "refs/tags/${MAJOR_TAG}" --force From a070165b25def0e3362b6967c6c0961f986c418d Mon Sep 17 00:00:00 2001 From: Jonah Lawrence Date: Thu, 17 Sep 2026 13:18:16 +0300 Subject: [PATCH 2/6] Clean up comments in update-major-version-tag.yml Removed comments for clarity and conciseness. --- .github/workflows/update-major-version-tag.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.github/workflows/update-major-version-tag.yml b/.github/workflows/update-major-version-tag.yml index 01ec3b25..4ab5b9bb 100644 --- a/.github/workflows/update-major-version-tag.yml +++ b/.github/workflows/update-major-version-tag.yml @@ -1,7 +1,5 @@ name: Update Major Version Tag -# Runs whenever a release is published (including "pre-release" if you want that too — -# adjust the `if` condition below to change scope). on: release: types: [published] @@ -12,8 +10,6 @@ permissions: jobs: update-major-tag: runs-on: ubuntu-latest - # Skip draft releases just in case; published releases won't normally be drafts, - # but this guards against workflow_dispatch/manual re-runs on stale events. if: ${{ !github.event.release.draft }} steps: - name: Checkout From 338cd38fce64dc0f92ffff96536fff45831bd821 Mon Sep 17 00:00:00 2001 From: Jonah Lawrence Date: Thu, 17 Sep 2026 13:20:58 +0300 Subject: [PATCH 3/6] Update checkout action to version 7 --- .github/workflows/update-major-version-tag.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/update-major-version-tag.yml b/.github/workflows/update-major-version-tag.yml index 4ab5b9bb..9308a811 100644 --- a/.github/workflows/update-major-version-tag.yml +++ b/.github/workflows/update-major-version-tag.yml @@ -13,7 +13,7 @@ jobs: if: ${{ !github.event.release.draft }} steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v7 with: fetch-depth: 0 From 2ee29d5a509375914e61a2a76dc4e3cbb05dcdfb Mon Sep 17 00:00:00 2001 From: Jonah Lawrence Date: Thu, 17 Sep 2026 13:24:50 +0300 Subject: [PATCH 4/6] Add concurrency and better escaping --- .github/workflows/update-major-version-tag.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.github/workflows/update-major-version-tag.yml b/.github/workflows/update-major-version-tag.yml index 9308a811..903a1b7b 100644 --- a/.github/workflows/update-major-version-tag.yml +++ b/.github/workflows/update-major-version-tag.yml @@ -7,6 +7,10 @@ on: permissions: contents: write +concurrency: + group: update-major-version-tag + cancel-in-progress: true + jobs: update-major-tag: runs-on: ubuntu-latest @@ -19,8 +23,10 @@ jobs: - name: Determine major version tag id: major + env: + RELEASE_TAG: ${{ github.event.release.tag_name }} run: | - tag="${{ github.event.release.tag_name }}" + tag="$RELEASE_TAG" # Expect semver-ish tags like v1.2.3 or 1.2.3 if [[ "$tag" =~ ^v?([0-9]+)\.[0-9]+\.[0-9]+(-.*)?$ ]]; then From 4512073ff6773e527b5f4f06d98c1d2a093eaf0d Mon Sep 17 00:00:00 2001 From: Jonah Lawrence Date: Thu, 17 Sep 2026 13:30:29 +0300 Subject: [PATCH 5/6] Modify concurrency settings and update tag handling --- .github/workflows/update-major-version-tag.yml | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/.github/workflows/update-major-version-tag.yml b/.github/workflows/update-major-version-tag.yml index 903a1b7b..fb46300b 100644 --- a/.github/workflows/update-major-version-tag.yml +++ b/.github/workflows/update-major-version-tag.yml @@ -9,7 +9,10 @@ permissions: concurrency: group: update-major-version-tag - cancel-in-progress: true + # Queue overlapping runs rather than cancelling them: cancelling could + # abandon an in-progress update to a different major tag (e.g. v1 vs v2) + # that just happens to be running at the same time. + cancel-in-progress: false jobs: update-major-tag: @@ -20,6 +23,7 @@ jobs: uses: actions/checkout@v7 with: fetch-depth: 0 + fetch-tags: true - name: Determine major version tag id: major @@ -54,14 +58,13 @@ jobs: - name: Move (or create) major version tag env: MAJOR_TAG: ${{ steps.major.outputs.major_tag }} - RELEASE_SHA: ${{ github.event.release.target_commitish }} + RELEASE_TAG: ${{ github.event.release.tag_name }} run: | # target_commitish is usually a branch name for tags created via the UI/API, # so resolve it to the actual commit the release's tag points at instead. - release_tag="${{ github.event.release.tag_name }}" - commit_sha="$(git rev-list -n 1 "$release_tag")" + commit_sha="$(git rev-list -n 1 "$RELEASE_TAG")" - echo "Pointing ${MAJOR_TAG} at ${commit_sha} (release ${release_tag})" + echo "Pointing ${MAJOR_TAG} at ${commit_sha} (release ${RELEASE_TAG})" - git tag -fa "$MAJOR_TAG" "$commit_sha" -m "Update ${MAJOR_TAG} to ${release_tag}" + git tag -fa "$MAJOR_TAG" "$commit_sha" -m "Update ${MAJOR_TAG} to ${RELEASE_TAG}" git push origin "refs/tags/${MAJOR_TAG}" --force From cf1d6b2ab94e768fe1b20e8120b98c007a97998c Mon Sep 17 00:00:00 2001 From: Jonah Lawrence Date: Thu, 17 Sep 2026 13:37:45 +0300 Subject: [PATCH 6/6] Update concurrency to cancel in-progress runs Change concurrency setting to cancel in-progress updates. --- .github/workflows/update-major-version-tag.yml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/.github/workflows/update-major-version-tag.yml b/.github/workflows/update-major-version-tag.yml index fb46300b..a55431d3 100644 --- a/.github/workflows/update-major-version-tag.yml +++ b/.github/workflows/update-major-version-tag.yml @@ -9,10 +9,8 @@ permissions: concurrency: group: update-major-version-tag - # Queue overlapping runs rather than cancelling them: cancelling could - # abandon an in-progress update to a different major tag (e.g. v1 vs v2) - # that just happens to be running at the same time. - cancel-in-progress: false + # assume linear tag progression (not updating v1 and v2 at the same time) + cancel-in-progress: true jobs: update-major-tag: