feat: retry createCommitOnBranch on stale-head conflict#153
Closed
smitthakkar96 wants to merge 1 commit into
Closed
feat: retry createCommitOnBranch on stale-head conflict#153smitthakkar96 wants to merge 1 commit into
smitthakkar96 wants to merge 1 commit into
Conversation
1991054 to
e76f548
Compare
When a concurrent push moves the branch head while a commit is being
prepared, createCommitOnBranch fails with a STALE_DATA conflict
("Expected branch to point to ... Pull and try again."). Add opt-in
--retries / --retry-wait (GHCOMMIT_RETRIES / GHCOMMIT_RETRY_WAIT) so the
tool re-reads the current branch head and re-applies the same file
changes on top of it, retrying with exponential backoff and jitter via
github.com/cenkalti/backoff/v7.
The mutation only touches the paths being committed, so re-applying on the
refreshed head preserves files changed by the concurrent push and does
last-write-wins on the committed paths. --retries 0 (the default) makes a
single attempt whose error is unwrapped from the RetryError so its output
is identical to before; behavior is unchanged unless retry is explicitly
requested. Non-conflict errors are marked permanent and never retried.
The head refresh reuses the already-configured githubv4 client so the
GITHUB_GRAPHQL_URL (GHES) endpoint is honored. The retry orchestration is
extracted into commitWithRetry and covered by tests that drive a real
githubv4 client against a mocked GraphQL server (testify assertions):
conflict -> head refresh -> retry -> success, retry exhaustion, and
no-retry on non-conflict errors.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PbmGosuc83bRrRXD1v5m8F
e76f548 to
e256cf3
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What & why
When a concurrent push moves the branch head while a commit is being prepared,
createCommitOnBranchfails with aSTALE_DATAconflict:This adds opt-in retry so the tool recovers instead of failing hard.
Changes
--retries/--retry-waitflags (GHCOMMIT_RETRIES/GHCOMMIT_RETRY_WAIT, defaults0/2s). The singleclient.Mutateis wrapped in a bounded loop: on a stale-head conflict it re-reads the current branch head, setsExpectedHeadOid, and re-applies the same file changes, up to--retriestimes with exponential backoff + jitter.isStaleHeadConflict— small, unit-tested predicate (case-insensitive match onexpected branch to point to/pull and try again). Unrelated errors never retry.currentHeadOid— head refresh via a GraphQL query that reuses the already-configured client, soGITHUB_GRAPHQL_URL(GHES) is honored.