From 0a6d9dca9d1cb71413c9085410e28e0c4afdca3f Mon Sep 17 00:00:00 2001 From: Yuriy Andamasov Date: Sun, 10 May 2026 23:33:16 +0300 Subject: ci: harden update-version-tags against stale re-runs and silent failures MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two improvements to .github/workflows/update-version-tags.yml, bundled because they touch the same code block: 1. HEAD-equivalence guard. GitHub's "Re-run jobs" replays the original event SHA, which for this workflow would move tag rolling/1.5/1.4 backward to a stale commit. Compare github.sha against the live branch HEAD via the API and exit 0 with a log line if they differ. 2. PATCH-first with 404-only fallback to POST. The previous "GET probe then PATCH or POST" pattern silently fell through to POST on any gh-api error (auth, rate-limit, 5xx), which would attempt to create a tag that already exists and mask the real failure. Now the fallback to POST fires only on HTTP 404; every other error is re-emitted to stderr and fails the job. Backport to circinus and sagitta after merge. 🤖 Generated by [robots](https://vyos.io) --- .github/workflows/update-version-tags.yml | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) (limited to '.github') diff --git a/.github/workflows/update-version-tags.yml b/.github/workflows/update-version-tags.yml index 35a87d61..e93f63c8 100644 --- a/.github/workflows/update-version-tags.yml +++ b/.github/workflows/update-version-tags.yml @@ -35,11 +35,29 @@ jobs: sagitta) TAG=1.4 ;; *) echo "Unexpected branch: $BRANCH" >&2; exit 1 ;; esac + + # Skip stale re-runs: GitHub's "Re-run jobs" replays the original + # event SHA, which would move the version tag backward to a stale + # commit. Compare event SHA against the current branch HEAD. + HEAD_SHA="$(gh api "repos/$REPO/branches/$BRANCH" --jq '.commit.sha')" + if [ "$HEAD_SHA" != "$SHA" ]; then + echo "Skipping stale run: event SHA=$SHA, current $BRANCH HEAD=$HEAD_SHA" + exit 0 + fi + echo "Pointing tag '$TAG' at $SHA (branch $BRANCH)" - if gh api "repos/$REPO/git/ref/tags/$TAG" >/dev/null 2>&1; then - gh api -X PATCH "repos/$REPO/git/refs/tags/$TAG" \ - -f sha="$SHA" -F force=true - else - gh api -X POST "repos/$REPO/git/refs" \ - -f ref="refs/tags/$TAG" -f sha="$SHA" + + # PATCH the tag if it exists; create on 404; fail loud on any other + # gh-api error (auth, rate-limit, 5xx) instead of silently falling + # through to POST. + patch_err="" + if ! patch_err="$(gh api -X PATCH "repos/$REPO/git/refs/tags/$TAG" \ + -f sha="$SHA" -F force=true 2>&1)"; then + if grep -q "HTTP 404" <<<"$patch_err"; then + gh api -X POST "repos/$REPO/git/refs" \ + -f ref="refs/tags/$TAG" -f sha="$SHA" + else + echo "$patch_err" >&2 + exit 1 + fi fi -- cgit v1.2.3 From 878ea77e4bb891f8de026edc5a4444436e054add Mon Sep 17 00:00:00 2001 From: Yuriy Andamasov Date: Sun, 10 May 2026 23:52:06 +0300 Subject: ci: scope update-version-tags concurrency group by SHA MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Copilot review on PR #1953 surfaced an edge case the HEAD guard alone doesn't fully cover: with cancel-in-progress: true and a per-branch concurrency group, a stale "Re-run jobs" replay can cancel the in-progress run for the current branch HEAD. The stale re-run then hits the HEAD guard and exits 0, leaving the tag un-advanced until the next push. Including github.sha in the concurrency group means different commits land in different groups and never cancel each other. Same-SHA re-runs still deduplicate (they share the group), and the HEAD guard handles the case where a stale re-run beats the current-HEAD run to start. 🤖 Generated by [robots](https://vyos.io) --- .github/workflows/update-version-tags.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to '.github') diff --git a/.github/workflows/update-version-tags.yml b/.github/workflows/update-version-tags.yml index e93f63c8..04ccd1e4 100644 --- a/.github/workflows/update-version-tags.yml +++ b/.github/workflows/update-version-tags.yml @@ -14,7 +14,10 @@ permissions: contents: write concurrency: - group: version-tag-${{ github.ref_name }} + # Include github.sha so a stale "Re-run jobs" replay (which carries the + # original SHA) cannot cancel an in-progress run for the current branch + # HEAD. Same-SHA re-runs still deduplicate. + group: version-tag-${{ github.ref_name }}-${{ github.sha }} cancel-in-progress: true jobs: -- cgit v1.2.3