fix: recover fork PR re-runs when GitHub omits PR metadata#2655
Conversation
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #2655 +/- ##
==========================================
+ Coverage 59.77% 59.87% +0.10%
==========================================
Files 210 210
Lines 21135 21180 +45
==========================================
+ Hits 12633 12682 +49
+ Misses 7707 7703 -4
Partials 795 795 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Code Review
This pull request introduces a fallback mechanism to resolve pull requests by SHA when the standard commit API fails, which is particularly useful for fork PRs. It also adds logic to extract pull request information directly from the check_run event. Feedback focuses on ensuring consistency and handling ambiguity when multiple pull requests might match a single SHA or check run, suggesting the use of existing helper functions to validate that only a single open pull request is processed.
3282631 to
212adf3
Compare
|
tested on dogfooding as working |
5f94900 to
8a5873e
Compare
|
|
||
| // ListPullRequestsWithCommit may return no matches for fork PR commits. | ||
| v.Logger.Infof("No PR found via commits API for SHA %s, falling back to open PR listing", runevent.SHA) | ||
| return v.findOpenPullRequestBySHA(ctx, runevent.Organization, runevent.Repository, runevent.SHA) |
There was a problem hiding this comment.
can we call the findOpenPullRequestBySHA only if its fork because if its not fork and there is no matching PRs as well then it would be just redundant API calls! (hint: event.pull_request.head.fork)
There was a problem hiding this comment.
the whole reason we end up here is that github stripped the PR metadata from the webhook — there's no checkSuite.PullRequests, no checkRun.PullRequests, nothing. so there's no event.pull_request.head.fork to look at either, that data is exactly what's missing. the fallback exists precisely because we have zero PR context to work with.
c6a4c49 to
6ecab48
Compare
| if len(checkSuite.PullRequests) > 0 { | ||
| runevent.PullRequestNumber = checkSuite.PullRequests[0].GetNumber() | ||
| runevent.TriggerTarget = triggertype.PullRequest | ||
| v.Logger.Infof("Recheck of PR %s/%s#%d has been requested", runevent.Organization, runevent.Repository, runevent.PullRequestNumber) | ||
| return v.getPullRequest(ctx, runevent) | ||
| } |
There was a problem hiding this comment.
| if len(checkSuite.PullRequests) > 0 { | |
| runevent.PullRequestNumber = checkSuite.PullRequests[0].GetNumber() | |
| runevent.TriggerTarget = triggertype.PullRequest | |
| v.Logger.Infof("Recheck of PR %s/%s#%d has been requested", runevent.Organization, runevent.Repository, runevent.PullRequestNumber) | |
| return v.getPullRequest(ctx, runevent) | |
| } |
There was a problem hiding this comment.
you can delete this as you're already doing this on line 557 below
There was a problem hiding this comment.
these are two different things they come from different levels of the webhook payload and github can populate one without the other. can't remove the first block.
6ecab48 to
9319477
Compare
chmouel
left a comment
There was a problem hiding this comment.
Code review: found 2 issue(s).
| } | ||
| if runevent.HeadBranch == "" { | ||
| return nil, fmt.Errorf("cannot determine branch for check_run rerequest: head_branch is null and no associated PR found for SHA %s", runevent.SHA) | ||
| if pr != nil { |
There was a problem hiding this comment.
This still leaves the fork rerun authorized as the PR author rather than the user who clicked Re-run. runevent.Sender is empty on this resolved-PR path, so populateRunEventFromPullRequest fills it with pr.GetUser().GetLogin(). The later non-push ACL check then evaluates the external fork contributor, and /ok-to-test replay does not handle CheckRunEvent, so a maintainer-rerequested fork PR can still be denied after this fallback successfully finds it. Set runevent.Sender and v.userType from event.GetSender() before returning the PR path, like the push path below does.
There was a problem hiding this comment.
Addressed in 6eb152f: rerun events now keep the GitHub actor who clicked Re-run as runevent.Sender before PR population, so the ACL check no longer falls back to the fork PR author.
| Title: github.Ptr("fork PR"), | ||
| }, | ||
| }, | ||
| "/repos/owner/reponame/pulls/987": github.PullRequest{ |
There was a problem hiding this comment.
This /pulls/987 fixture is never used by the fork fallback path: after /pulls returns the matching PR, the code calls populateRunEventFromPullRequest(runevent, pr) directly and never fetches the single-PR endpoint. That makes the test look like it covers a full PR fetch when it only relies on the list response. Please remove the dead handler or add assertions for fields populated from the list-response PR so the intended coverage is explicit.
There was a problem hiding this comment.
Addressed in 6eb152f: the unused /pulls/987 fixture was removed, and the test now asserts fields populated from the list-response PR so the fork fallback coverage is explicit.
When someone clicks Re-run on a Pipelines as Code check for a pull request coming from a fork, GitHub can leave out the usual pull request details in the webhook payload. That left PAC with no obvious way to tell which pull request the check belonged to, so the re-run stopped with an error instead of starting again. This change teaches PAC to keep looking in a more practical way. If the first GitHub API says it cannot find the pull request for the commit, PAC now lists open pull requests in the repository and matches the one whose head commit SHA is the same. In simple terms: when GitHub does not hand us the answer directly, we now look through the open pull requests and find the one built from that exact commit. The change also checks pull request data attached directly to the check_run event before falling back to SHA-based lookup, and the tests now cover both the new fork pull request path and the empty-result error cases. Signed-off-by: Chmouel Boudjnah <chmouel@redhat.com>
9319477 to
6eb152f
Compare
|
Jira for the GitHub fork PR rerun fix in this PR: SRVKP-12590. |
When GitHub receives a Re-run request for a Pipelines as Code check tied to a pull request from a fork, the webhook payload can omit the usual pull request metadata. PAC could already recover by looking up pull requests for the head SHA, but fork PRs still failed when GitHub's
commits/{sha}/pullsAPI returned no matches.This change makes rerequest handling more resilient and keeps the selection rules safe:
📝 Description of the Change
Improve GitHub rerequest PR resolution so fork pull requests can be recovered safely even when GitHub omits PR metadata or the commit lookup API returns no match.
🔗 Linked GitHub Issue
Not linked.
🧪 Testing Strategy
Ran:
go test ./pkg/provider/github🤖 AI Assistance
AI assistance was used to help draft and refine the code change, tests, and PR description. The resulting changes were reviewed and validated with the package test run above.
✅ Submitter Checklist
fix:,feat:) matches the "Type of Change" I selected above.make testandmake lintlocally to check for and fix anyissues. For an efficient workflow, I have considered installing
pre-commit and running
pre-commit installtoautomate these checks.