Skip to content

ci: resolve the PR by head repo + branch, not by commit sha - #490

Merged
Loup-Garou911XD merged 1 commit into
bombsquad-community:mainfrom
Loup-Garou911XD:ci/resolve-pr-by-head
Sep 8, 2026
Merged

Loup-Garou911XD merged 1 commit into
bombsquad-community:mainfrom
Loup-Garou911XD:ci/resolve-pr-by-head

Conversation

@Loup-Garou911XD

Copy link
Copy Markdown
Member

The bug

PR Apply has never once applied fixups to a fork PR.

It resolved the target PR through repos/{repo}/commits/{sha}/pulls, and that endpoint cannot answer for a fork PR's head commit: the commit is not reachable from any ref of this repo, so the association index has nothing to return and the call yields []. This is not eventual consistency that a longer poll rides out, it simply never resolves.

Verified against the live API: that call returns 489 for 9def131 now, but only because merging put the commit into main's history. During run 34192652242 it was empty for the full 50s poll while PR #489 was open with exactly that head.

Why nobody noticed

The failure used to be invisible. Before the loud-failure change in #484, the lookup fell through to skip, which exits 0, so the job painted itself green having applied nothing. Run 34016889713 is a "success" that did exactly that:

Not exactly one PR associated with dcb50fd296a645ccca9ddbf21c5f935692c2851c; skipping.

That is how #479 reached main unstamped and broke it. #484 correctly turned the silent skip into a hard failure, which is why every fork PR has gone red at that step since: 34018273545, 34023650032, 34040502180, 34042614720, 34048956687, 34192652242.

So #484 did not cause this. It exposed it.

The fix

Look the PR up by head repo owner + head branch instead. That filter is exact, is available the moment the PR exists, and narrows on precisely the fields HARD RULE 3 already requires the resolved PR to match.

Nothing is relaxed. State, base, head repo, head branch and head sha are all still pinned against the workflow_run payload before anything is applied, so a run can still only ever write to the branch it came from.

Two smaller decisions:

  • state=all rather than state=open, so a PR merged between PR Check and this run still resolves and takes the existing PR not open; skipping path instead of looking unidentifiable.
  • Several PRs from one head branch is ordinary history for a reused branch, not the sha-adoption ambiguity HARD RULE 3 guards against. Every candidate shares the same head repo and branch by construction, so the newest by number wins rather than failing closed.

Owner and branch are shape-checked before they enter the URL.

Verification

YAML parses, the extracted step passes bash -n, and the new lookup plus its jq selection were run against the live API for #489.

Note this cannot go fully green until the secrets.PAT expiry is resolved (see the companion PR), since PR Apply's own merge to main runs the broken ci.yml path.

🤖 Generated with Claude Code

https://claude.ai/code/session_01CSZrwNCXvibEJ9PXCW1uqi

PR Apply has never once applied fixups to a fork PR. It resolved the
target PR through repos/{repo}/commits/{sha}/pulls, and that endpoint
cannot answer for a fork PR's head commit: the commit is not reachable
from any ref of this repo, so the association index has nothing to
return and the call yields [] forever. This is not eventual consistency
that a longer poll would ride out.

The failure used to be invisible. Before the loud-failure change the
lookup fell through to `skip`, which exits 0, so the job painted itself
green having applied nothing - which is how bombsquad-community#479 reached main unstamped.
Since then it fails loudly instead, correctly, and every fork PR has gone
red at that step (runs 34018273545, 34023650032, 34040502180, 34042614720,
34048956687, 34192652242).

Look the PR up by head repo owner + head branch instead. That filter is
exact, is available the moment the PR exists, and narrows on precisely
the fields HARD RULE 3 already requires the resolved PR to match. Nothing
is relaxed: state, base, head repo, head branch and head sha are all
still pinned against the workflow_run payload before anything is applied,
so a run can still only ever write to the branch it came from.

state=all, not state=open, so a PR merged between PR Check and this run
still resolves and takes the existing "PR not open; skipping" path rather
than looking unidentifiable. Several PRs from one head branch is ordinary
history for a reused branch, not the sha-adoption ambiguity HARD RULE 3
guards against - every candidate shares the same head repo and branch by
construction - so the newest by number wins instead of failing closed.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CSZrwNCXvibEJ9PXCW1uqi
@Loup-Garou911XD
Loup-Garou911XD merged commit dd921e0 into bombsquad-community:main Sep 8, 2026
1 check passed
@Loup-Garou911XD
Loup-Garou911XD deleted the ci/resolve-pr-by-head branch September 28, 2026 09:18
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.

1 participant