From 995c6635de2f1b6796187f68c0260c90f7cc8c1a Mon Sep 17 00:00:00 2001 From: Ilja Livenson Date: Thu, 9 Jul 2026 16:37:01 +0300 Subject: [PATCH] Make npm publish resilient to concurrent pushes to main The publish job bumps the version (npm version prerelease) and pushes the commit back to main. When main advances between checkout and push (a concurrent SDK-regen push, or another publish run), the bare 'git push' is rejected with a non-fast-forward 'fetch first' error and the whole publish aborts. Serialize publish runs with a concurrency group, and make the push rebase onto origin/main and retry so a racing push no longer fails the release. --- .github/workflows/npm-publish.yml | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/.github/workflows/npm-publish.yml b/.github/workflows/npm-publish.yml index 55817f3..f546b69 100644 --- a/.github/workflows/npm-publish.yml +++ b/.github/workflows/npm-publish.yml @@ -16,6 +16,15 @@ permissions: id-token: write contents: write +# Serialize publish runs so each version-bump commit is pushed onto an +# up-to-date main. Without this, two runs (or a concurrent push to the same +# ref) can advance main between checkout and push, producing a non-fast-forward +# "Updates were rejected ... (fetch first)" error. cancel-in-progress: false so +# queued runs still publish rather than being dropped. +concurrency: + group: publish-npm + cancel-in-progress: false + jobs: publish-npm: runs-on: ubuntu-latest @@ -50,7 +59,21 @@ jobs: npm publish else npm version prerelease --preid=dev - git push + # Push the version-bump commit, rebasing and retrying if main + # advanced meanwhile (e.g. a concurrent SDK-regen push to src/**). + # A bare `git push` fails with a non-fast-forward rejection in that + # case and aborts the whole publish. + attempts=0 + until git push origin HEAD:main; do + attempts=$((attempts + 1)) + if [ "$attempts" -ge 5 ]; then + echo "::error::Failed to push version bump after $attempts attempts" + exit 1 + fi + echo "Push rejected (attempt $attempts); rebasing onto origin/main and retrying..." + git pull --rebase origin main + sleep $((RANDOM % 5 + 2)) + done npm publish --tag dev fi