From a1205eaf44378ae91105f53a9796a302b7df22d8 Mon Sep 17 00:00:00 2001 From: Xianpeng Shen <3353385+shenxianpeng@users.noreply.github.com> Date: Wed, 4 Nov 2026 16:39:46 +0000 Subject: [PATCH 1/3] fix: move the rolling tag of the released major version The release workflow took the major version from the newest tag in the repository. Once any v3 tag exists, publishing a v2 patch would move v3 to the v2 code and leave v2 behind. Now the major version comes from the release tag itself. A manual run takes the release tag as `ref` (no default), derives the rolling tag from it, and refuses a commit without a vX.Y.Z tag or a rolling tag of another major version. --- .github/workflows/release.yml | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index a1bfaf1b..25994973 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -5,14 +5,12 @@ on: types: [released] workflow_dispatch: inputs: - tag: - description: 'which tag to update to' - default: 'v2' - required: true ref: - description: 'which branch to update the tag on' - default: 'main' + description: 'release tag to point the rolling tag at, e.g. v2.24.1' required: true + tag: + description: 'rolling tag to update, e.g. v2 (blank = major version of ref)' + required: false permissions: contents: write @@ -33,8 +31,22 @@ jobs: - name: Update rolling tag env: INPUT_TAG: ${{ inputs.tag }} + RELEASE_TAG: ${{ github.event.release.tag_name }} run: | - # Use the tag given by hand, else the major version of the latest tag - TAG="${INPUT_TAG:-$(git tag --list --sort=-v:refname | head -n1 | cut -d. -f1)}" + # The rolling tag follows the major version of the release tag on the + # checked out commit, not of the newest tag in the repository: a v2 + # patch published after v3 must move v2, not v3. + RELEASE="${RELEASE_TAG:-$(git describe --tags --exact-match --match 'v[0-9]*.*' --exclude '*-*' HEAD || true)}" + if ! [[ "$RELEASE" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then + echo "::error title=Not a release tag::'${RELEASE}' is not a vX.Y.Z release tag; give the release tag as ref" + exit 1 + fi + MAJOR="${RELEASE%%.*}" + TAG="${INPUT_TAG:-$MAJOR}" + if [ "$TAG" != "$MAJOR" ]; then + echo "::error title=Major version mismatch::$TAG cannot point at $RELEASE" + exit 1 + fi + echo "Moving $TAG to $RELEASE ($(git rev-parse --short HEAD))" git tag --force --annotate "$TAG" --message "Retag $TAG" git push origin "$TAG" --force From e2675863944887057b3d703b401cc17e5e0601b0 Mon Sep 17 00:00:00 2001 From: Xianpeng Shen <3353385+shenxianpeng@users.noreply.github.com> Date: Wed, 4 Nov 2026 16:53:32 +0000 Subject: [PATCH 2/3] fix: take the release tag from ref on manual runs A commit can carry release tags of two majors, so deriving the tag from HEAD could pick the other major. Use the ref input itself, as its description says. --- .github/workflows/release.yml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 25994973..640f9f2b 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -31,12 +31,13 @@ jobs: - name: Update rolling tag env: INPUT_TAG: ${{ inputs.tag }} + INPUT_REF: ${{ inputs.ref }} RELEASE_TAG: ${{ github.event.release.tag_name }} run: | - # The rolling tag follows the major version of the release tag on the - # checked out commit, not of the newest tag in the repository: a v2 - # patch published after v3 must move v2, not v3. - RELEASE="${RELEASE_TAG:-$(git describe --tags --exact-match --match 'v[0-9]*.*' --exclude '*-*' HEAD || true)}" + # The rolling tag follows the major version of the published release + # (or the release tag given as ref), not of the newest tag in the + # repository: a v2 patch published after v3 must move v2, not v3. + RELEASE="${RELEASE_TAG:-$INPUT_REF}" if ! [[ "$RELEASE" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then echo "::error title=Not a release tag::'${RELEASE}' is not a vX.Y.Z release tag; give the release tag as ref" exit 1 From 7fd5f4dc8a9bb8f880e5233775f0cb74811569f4 Mon Sep 17 00:00:00 2001 From: Xianpeng Shen <3353385+shenxianpeng@users.noreply.github.com> Date: Wed, 4 Nov 2026 16:58:00 +0000 Subject: [PATCH 3/3] fix: check that the release tag is the checked out commit A branch named like the release tag would be checked out instead of the tag. Refuse to move the rolling tag unless the release tag exists and points at HEAD. --- .github/workflows/release.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 640f9f2b..fce16f49 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -48,6 +48,11 @@ jobs: echo "::error title=Major version mismatch::$TAG cannot point at $RELEASE" exit 1 fi + # A branch named like the tag would be checked out instead of the tag + if [ "$(git rev-parse HEAD)" != "$(git rev-parse --verify --quiet "refs/tags/$RELEASE^{commit}")" ]; then + echo "::error title=Commit mismatch::tag $RELEASE is missing or not the checked out commit" + exit 1 + fi echo "Moving $TAG to $RELEASE ($(git rev-parse --short HEAD))" git tag --force --annotate "$TAG" --message "Retag $TAG" git push origin "$TAG" --force