Skip to content

Prevent push coverage from matching fork pull requests - #33

Merged
cassiomarques merged 3 commits into
mainfrom
cassiomarques/scope-push-pr-lookup
Oct 1, 2026
Merged

cassiomarques merged 3 commits into
mainfrom
cassiomarques/scope-push-pr-lookup

Conversation

@cassiomarques

@cassiomarques cassiomarques commented Sep 29, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Prevent coverage generated by a non-default branch push from being associated with an unrelated fork pull request whose head branch has the same name.

Background

For push-only workflows, the action discovers an open pull request using the pushed branch name:

gh pr list --head <branch>

GitHub CLI matches that name across both internal and fork head repositories. If an internal branch and a fork use the same branch name, the action could select the fork PR and attribute the internal branch's coverage to it.

v1.4.3 already fixed the default-branch version of this problem by ensuring default-branch pushes never perform PR discovery. This PR fixes the remaining non-default branch path.

Implementation

The lookup now requests structured pull request metadata and accepts candidates only when:

  • The head branch exactly matches the pushed branch.
  • The full head repository exactly matches GITHUB_REPOSITORY.

The resulting behavior is:

  • No internal match: Skip the unsupported non-default branch upload, preserving the behavior introduced in v1.4.3.
  • One internal match: Upload coverage against that pull request, preserving existing behavior regardless of its target branch.
  • Multiple internal matches: Prefer the pull request targeting the repository's default branch. Coverage comparisons currently use the default branch as their baseline, and GitHub prevents multiple open pull requests with the same source and target branches.
  • Multiple matches without a unique default-branch target: Skip successfully with a warning rather than selecting arbitrarily or failing CI.
  • Fork or deleted-repository matches: Ignore them.
  • Invalid CLI output or CLI failure: Fail with an actionable lookup error.

The public action interface and required permissions are unchanged.

Compatibility and trade-offs

A repository branch can have multiple open pull requests when those pull requests target different base branches. A push event does not identify one of them as the intended pull request.

Previously, the action silently selected whichever result appeared first. This PR uses the default-branch target when one exists because that aligns with the current coverage comparison baseline. If the remaining candidates are still ambiguous, skipping successfully avoids both incorrect attribution and turning valid repository state into a failing required check.

A workflow using the pull_request event remains the recommended option when each pull request needs an unambiguous upload.

Test plan

Regression tests cover:

  • An internal PR and fork PR sharing the same branch name.
  • A same-named fork PR without an internal match.
  • One exact internal match.
  • Multiple internal PRs with a unique default-branch target.
  • Multiple internal PRs without a unique default-branch target.
  • Ambiguous lookup skipping successfully without failing CI.
  • A deleted fork repository.
  • Invalid GitHub CLI JSON.
  • Existing GitHub CLI failure and missing-CLI behavior.
  • Default-branch pushes continuing to bypass PR discovery.
  • Shell-metacharacter branch names remaining literal data after the lookup change.

Copilot AI balanced review requested due to automatic review settings September 29, 2026 14:57

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot review overview

🟡 Changes recommended

Early candidate selection can accept partially invalid GitHub CLI output instead of failing safely.

Review effort: Balanced
Findings: 1 Medium severity

Open (1)
What changed in this PR

Prevents push coverage from being attributed to same-named branches in fork repositories.

Changes:

  • Filters PR candidates by branch and head repository.
  • Handles ambiguous matches with warnings.
  • Adds regression tests and documentation.
File Description
resolve_upload_context.py Implements structured PR selection.
test_resolve_upload_context.py Adds lookup regression tests.
README.md Documents ambiguous PR behavior.
docs/​workflow-strategies.md Updates push-workflow guidance.
CHANGELOG.md Records the fixes.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread resolve_upload_context.py Outdated

@jkbschmid jkbschmid left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Only a few nits, looks good to me conceptually 👌
Feel free to ignore any nits that are unrelated to this PR.

Comment thread resolve_upload_context.py Outdated
Comment thread resolve_upload_context.py Outdated
Comment thread resolve_upload_context.py Outdated
Comment thread resolve_upload_context.py Outdated
Comment thread test_resolve_upload_context.py

@jkbschmid jkbschmid left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Thanks for also addressing the nits unrelated to this PR! ❤️

@cassiomarques
cassiomarques merged commit cd112d6 into main Oct 1, 2026
2 checks passed
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.

Push to default branch attributes coverage to an unrelated fork PR with a same-named head branch

3 participants