Skip to content

fix(release): push version tags in one atomic push (avoid commit_refs race)#2195

Merged
xuyushun441-sys merged 2 commits into
mainfrom
fix/release-atomic-tag-push
Jun 22, 2026
Merged

fix(release): push version tags in one atomic push (avoid commit_refs race)#2195
xuyushun441-sys merged 2 commits into
mainfrom
fix/release-atomic-tag-push

Conversation

@xuyushun441-sys

Copy link
Copy Markdown
Contributor

Problem

The Release job failed on #2191 with remote: fatal error in commit_refs and ~half the version tags [remote rejected] ... (failure).

Root cause: changeset publish publishes every package to npm and creates one git tag per package. changesets/action then pushes those tags by firing one git push origin <tag> per tag concurrently (every [command]/usr/bin/git push in the log shares the same millisecond timestamp). With our large Changesets fixed group (~73 packages bumping in lockstep), that burst of simultaneous ref-creation pushes races GitHub's ref backend → fatal error in commit_refs → ~half the tags rejected. npm publishing had already fully succeeded by then, so the job fails after the artifacts are live.

Concrete fallout on 10.0.0: all 73 packages published to npm, but only 54/73 git tags reached the remote — 19 are missing and no future release run will recreate them (changeset only tags what it publishes).

Note: the follow-up run (#2193) went green only because everything was already on npm, so it published nothing and pushed no tags. The bug is masked, not fixed, and recurs on the next multi-package bump.

Fix

Route the publish command through scripts/release-publish.sh:

changeset publish
git push origin --tags

All new tags go up in a single atomic git push = one ref transaction, so there's no concurrency to race. The action's subsequent per-tag pushes become harmless no-ops (every tag already exists on the remote at the same SHA).

Files

  • scripts/release-publish.sh — new, documented wrapper (publish + atomic tag push)
  • package.jsonrelease script now ends in the wrapper instead of bare changeset publish
  • .github/workflows/release.yml — comment explaining why

Not covered here

Backfilling the 19 10.0.0 tags already missing from the remote is a separate one-time op (these packages are published, so changeset won't re-tag them).

🤖 Generated with Claude Code

… race)

changeset publish creates a git tag per package; changesets/action then
pushes them with one concurrent `git push origin <tag>` per tag. With the
large Changesets "fixed" group (~73 packages bumping in lockstep), that
burst of simultaneous ref-creation pushes races GitHub's ref backend, which
returns `remote: fatal error in commit_refs` and rejects ~half the tags —
failing the Release job even though npm publishing already fully succeeded
(#2191: 54/73 tags pushed, 19 rejected).

Route the publish command through scripts/release-publish.sh, which runs
`changeset publish` then pushes ALL new tags in a SINGLE atomic
`git push origin --tags`. One push is one ref transaction, so there is no
concurrency to race; the action's later per-tag pushes become no-ops
because every tag already exists on the remote.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@vercel

vercel Bot commented Jun 22, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
spec Ready Ready Preview, Comment Jun 22, 2026 11:20am

Request Review

@github-actions github-actions Bot added ci/cd dependencies Pull requests that update a dependency file size/s labels Jun 22, 2026
@xuyushun441-sys xuyushun441-sys added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Jun 22, 2026
@xuyushun441-sys xuyushun441-sys merged commit de9508d into main Jun 22, 2026
16 checks passed
@xuyushun441-sys xuyushun441-sys deleted the fix/release-atomic-tag-push branch June 22, 2026 11:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci/cd dependencies Pull requests that update a dependency file size/s skip-changeset PR has no user-facing published change; bypasses the changeset gate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants