Skip to content

Add retry to latestPullRequest for commit-to-PR index race condition#333

Merged
Songmu merged 1 commit into
Songmu:mainfrom
babarot:babarot/retry-latest-pull-request
Apr 5, 2026
Merged

Add retry to latestPullRequest for commit-to-PR index race condition#333
Songmu merged 1 commit into
Songmu:mainfrom
babarot:babarot/retry-latest-pull-request

Conversation

@babarot
Copy link
Copy Markdown
Contributor

@babarot babarot commented Apr 3, 2026

Thanks for building tagpr! I use it both at work and in personal projects and it's been great.

Summary

Add retry logic to latestPullRequest() so that tagpr can tolerate the GitHub API's eventual consistency when resolving commits to pull requests.

Problem

latestPullRequest() calls ListPullRequestsWithCommit once with no retry. The GitHub API endpoint GET /repos/{owner}/{repo}/commits/{sha}/pulls depends on an internal index that associates commits with PRs. This index update is asynchronous — when tagpr queries the API within seconds of a merge, the endpoint may return an empty list.

When this happens, latestPullRequest returns (nil, nil), isTagPR(nil) returns false, and tagpr falls through to create a duplicate release PR instead of tagging the release.

Real-world example

In babarot/gh-infra, the following sequence occurred:

  1. PR #64 (a regular fix) was merged to main at 08:58:58
  2. PR #62 (a tagpr release PR for v0.7.0) was merged at 08:59:39
  3. The Release workflow triggered for the PR configurable pull request template #62 merge commit (506696d)
  4. tagpr ran and called ListPullRequestsWithCommit for 506696d — the API returned an empty list (index not yet updated, only 13 seconds after merge)
  5. tagpr failed to detect its own release PR and created a duplicate PR #65 instead of tagging v0.7.0
  6. The v0.7.0 tag was never created

This was a regular merge commit (not squash), confirming that the race condition is not limited to squash merges as initially reported in #330.

GitHub's ListPullRequestsWithCommit API depends on an internal index
that associates commits with PRs. This index update is asynchronous,
so the endpoint may return an empty list when called immediately after
a merge. When this happens, tagpr fails to detect its own release PR
merge and falls through to create a duplicate release PR.

Add retry logic (3 attempts, 2s interval) to latestPullRequest() so
that transient empty responses are retried before giving up.
@Songmu Songmu merged commit 649202e into Songmu:main Apr 5, 2026
3 checks passed
@Songmu
Copy link
Copy Markdown
Owner

Songmu commented Apr 5, 2026

Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants