Skip to content

fix(gh): fix re-run button on Pull Requests#2597

Open
chmouel wants to merge 1 commit intotektoncd:mainfrom
chmouel:fix-gh-fix-re-run-button-on-pull-requests
Open

fix(gh): fix re-run button on Pull Requests#2597
chmouel wants to merge 1 commit intotektoncd:mainfrom
chmouel:fix-gh-fix-re-run-button-on-pull-requests

Conversation

@chmouel
Copy link
Copy Markdown
Member

@chmouel chmouel commented Mar 19, 2026

📝 Description of the Change

GitHub check_run and check_suite rerequests for fork PRs can have
a null head_branch and an empty pull_requests list. PAC was falling
back to treating these events as push events, causing the Re-run
button on PRs to have no effect.

When head_branch is null, fall back to looking up the associated PR
by commit SHA before deciding the event type. If a PR is found,
process as a PR rerequest. If not, return a clear error.

output.mp4

🔗 Linked Issue

Jira https://redhat.atlassian.net/browse/SRVKP-11161

🧪 Testing Strategy

  • Unit tests
  • Integration tests
  • End-to-end tests
  • Manual testing
  • Not Applicable

🤖 AI Assistance

AI assistance can be used for various tasks, such as code generation,
documentation, or testing.

Please indicate whether you have used AI assistance
for this PR and provide details if applicable.

  • I have not used any AI assistance for this PR.
  • I have used AI assistance for this PR.

Important

Slop will be simply rejected, if you are using AI assistance you need to make sure you
understand the code generated and that it meets the project's standards. you
need at least know how to run the code and deploy it (if needed). See
startpaac to make it easy
to deploy and test your code changes.

If the majority of the code in this PR was generated by an AI, please add a Co-authored-by trailer to your commit message.
For example:

Co-authored-by: Claude noreply@anthropic.com

✅ Submitter Checklist

  • 📝 My commit messages are clear, informative, and follow the project's How to write a git commit message guide. The Gitlint linter ensures in CI it's properly validated
  • ✨ I have ensured my commit message prefix (e.g., fix:, feat:) matches the "Type of Change" I selected above.
  • ♽ I have run make test and make lint locally to check for and fix any
    issues. For an efficient workflow, I have considered installing
    pre-commit and running pre-commit install to
    automate these checks.
  • 📖 I have added or updated documentation for any user-facing changes.
  • 🧪 I have added sufficient unit tests for my code changes.
  • 🎁 I have added end-to-end tests where feasible. See README for more details.
  • 🔎 I have addressed any CI test flakiness or provided a clear reason to bypass it.
  • If adding a provider feature, I have filled in the following and updated the provider documentation:
    • GitHub App
    • GitHub Webhook
    • Gitea/Forgejo
    • GitLab
    • Bitbucket Cloud
    • Bitbucket Data Center

@chmouel
Copy link
Copy Markdown
Member Author

chmouel commented Mar 19, 2026

/gemini review

@chmouel chmouel requested a review from Copilot March 19, 2026 14:42
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes GitHub check_run / check_suite “rerequested” handling for fork PRs where the webhook payload can have head_branch: null and an empty pull_requests list, by falling back to resolving the PR via commit SHA instead of misclassifying the event as a push.

Changes:

  • Update GitHub payload parsing to resolve PR rerequests by commit SHA when head_branch is missing.
  • Add unit tests covering the new SHA-resolution behavior and the error case when no PR is found.
  • Extend the GitHub GHE e2e rerequest test to exercise the null-head_branch check_run scenario; add a new JSON fixture.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 5 comments.

File Description
pkg/provider/github/parse_payload.go Adds SHA-based PR lookup fallback for rerequest events when head_branch is missing.
pkg/provider/github/parse_payload_test.go Adds unit tests for null-head_branch rerequest behavior (success + failure).
test/github_pullrequest_rerequest_test.go Adds an e2e scenario sending a check_run rerequest with null head_branch and empty PR list.
test/fixtures/check_suite_rerequest_null_branch.json Adds a fixture representing a null-head_branch check_suite/check_run rerequest payload.
Comments suppressed due to low confidence (1)

pkg/provider/github/parse_payload.go:495

  • In the check_run rerequest fallback where this is treated as a push event, runevent.TriggerTarget is never set (unlike handleCheckSuites, which sets it to "push"). Downstream logic (e.g., changed-files fetching/switches on TriggerTarget) may treat an empty TriggerTarget as unknown and skip important behavior. Set runevent.TriggerTarget = triggertype.Push (or "push") alongside runevent.EventType = "push" for consistency.
		runevent.BaseBranch = runevent.HeadBranch
		runevent.BaseURL = runevent.HeadURL
		runevent.EventType = "push"
		// we allow the rerequest user here, not the push user, i guess it's
		// fine because you can't do a rereq without being a github owner?
		runevent.Sender = event.GetSender().GetLogin()
		v.userType = event.GetSender().GetType()
		return runevent, nil

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

@chmouel
Copy link
Copy Markdown
Member Author

chmouel commented Mar 19, 2026

Review from Gemini Code

I've taken a deep look at this pull request. Here is my assessment:

The Problem:
GitHub's check_run and check_suite rerequested webhook payloads occasionally arrive with a null head_branch, particularly when triggered from the UI for pull requests without a full suite context. This caused the provider payload parser to either error out or incorrectly assume a push event when it shouldn't.

The Fix:
The introduced changes in pkg/provider/github/parse_payload.go correctly intercept cases where HeadBranch is empty and SHA is present. By falling back to getPullRequestsWithCommit, the code resolves the associated pull request directly via the GitHub API, reconstructing the missing context before continuing with v.getPullRequest(ctx, runevent). This is a clean and robust fallback.

Testing:

  • Unit Tests: Excellent additions in pkg/provider/github/parse_payload_test.go covering both check_run and check_suite scenarios where HeadBranch is null.
  • E2E Tests: A new test case in test/github_pullrequest_rerequest_test.go specifically verifies the "null head_branch" scenario dynamically, which is great for catching future regressions.
  • Test Fixtures: test/fixtures/check_suite_rerequest_null_branch.json correctly models the problematic webhook payload.

Conclusion:
The logic handles the edge case gracefully. The error handling is solid (failing fast if no PR is found). The tests are comprehensive. This looks good to merge. LGTM! 🚀

GitHub check_run and check_suite rerequests for fork PRs can have
a null head_branch and an empty pull_requests list. PAC was falling
back to treating these events as push events, causing the Re-run
button on PRs to have no effect.

When head_branch is null, fall back to looking up the associated PR
by commit SHA before deciding the event type. If a PR is found,
process as a PR rerequest. If not, return a clear error.

Signed-off-by: Chmouel Boudjnah <chmouel@redhat.com>
Assisted-by: Claude Sonnet 4.6 (via Claude Code)
Signed-off-by: Chmouel Boudjnah <chmouel@redhat.com>
@chmouel chmouel force-pushed the fix-gh-fix-re-run-button-on-pull-requests branch from 98e1889 to 7c8d958 Compare March 20, 2026 08:11
@chmouel
Copy link
Copy Markdown
Member Author

chmouel commented Mar 20, 2026

/test linters

@chmouel
Copy link
Copy Markdown
Member Author

chmouel commented Mar 20, 2026

/cancel linters

@chmouel
Copy link
Copy Markdown
Member Author

chmouel commented Mar 20, 2026

/retest

if len(event.GetCheckSuite().PullRequests) == 0 {
// If head_branch is null, try to find a PR by SHA before assuming push
if runevent.HeadBranch == "" && runevent.SHA != "" {
prs, err := v.getPullRequestsWithCommit(ctx, runevent.SHA, runevent.Organization, runevent.Repository, false)
Copy link
Copy Markdown
Member

@zakisk zakisk Mar 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it might be possible that there are multiple pull requests associated with the commit, so can you please research more how we can figure out that first PR is the one on which re-request is clicked?

runevent.PullRequestNumber = prs[0].GetNumber()
runevent.TriggerTarget = triggertype.PullRequest
v.Logger.Infof("Rerun of all checks on PR %s/%s#%d has been requested (resolved from SHA)", runevent.Organization, runevent.Repository, runevent.PullRequestNumber)
return v.getPullRequest(ctx, runevent)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if we've fetched the PR from getPullRequestsWithCommit then we don't need to call getPullRequest again here because we have PR object and we have all the info. and also it will open the door for A Time-of-Check to Time-of-Use (TOCTOU) race condition attack.

if len(event.GetCheckRun().GetCheckSuite().PullRequests) == 0 {
// If head_branch is null, try to find a PR by SHA before assuming push
if runevent.HeadBranch == "" && runevent.SHA != "" {
prs, err := v.getPullRequestsWithCommit(ctx, runevent.SHA, runevent.Organization, runevent.Repository, false)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same concerns here and below

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.

3 participants