Skip to content

fix(ci): reconcile PR from head SHA when the commit-PR index lags - #1445

Merged
Wibias merged 4 commits into
lidge-jun:devfrom
Wibias:ci/resolve-pr-fallback
Aug 11, 2026
Merged

fix(ci): reconcile PR from head SHA when the commit-PR index lags#1445
Wibias merged 4 commits into
lidge-jun:devfrom
Wibias:ci/resolve-pr-fallback

Conversation

@Wibias

@Wibias Wibias commented Aug 11, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • The resolve-pr job previously mapped a trusted CodeRabbit status SHA back to a PR using GitHub's commit-to-PR association index. That index can lag a fresh head push, returning zero matches for a genuine current head, so revalidation was silently skipped and newly posted CodeRabbit findings never re-drafted the PR (observed on fix(codex): stop recursive dynamic-launcher shims #1441).
  • When the index yields no unique match, the resolver now reconciles directly against the live open-PR list by head.sha — the same authoritative identity the write gate already uses. Resolution still requires exactly one open PR match, so a genuine ambiguity stays fail-closed.
  • The fallback is a read (pulls.list) and remains within the resolver job's pull-requests: read permission; no write scope is broadened.

Validation

  • bun test tests/ci-workflows.test.ts — pass (136/136, includes 4 new resolver scenarios)
  • node .github/scripts/enforce-pr-target.test.cjs — pass (18/18)
  • bun run typecheck — clean
  • bun run privacy:scan — pass

Review notes

  • New behavioural tests exercise the resolver through the existing harness: empty-index fallback, no-match skip, fresh-index direct resolve, and fail-closed on error.
  • The full bun run test suite crashed inside the Bun runtime (internal index out of bounds panic) under heavy local runner contention; that is a Bun bug, not a test failure. Tests covering this change pass in isolation.

Limitations

  • Fallback resolution depends on listing open PRs for the repository; a very large open-PR set is paginated (100 per page) like the existing stacked-base path.

Refs #1441

Summary by CodeRabbit

  • Bug Fixes
    • Improved pull request targeting for status events by validating the current commit before proceeding.
    • Added fallback matching when commit-to-pull-request associations are stale or unavailable.
    • Prevented processing when no unique pull request can be identified or lookup fails, reducing incorrect status updates.
  • Tests
    • Expanded coverage for stale associations, fallback resolution, ambiguous matches, missing matches, and lookup failures.

@github-actions

Copy link
Copy Markdown
Contributor

Deterministic PR hygiene checks passed.

@github-actions github-actions Bot added the bug Something isn't working label Aug 11, 2026
@coderabbitai

coderabbitai Bot commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 394c2e78-0f0c-42c4-912d-b8151f560473

📥 Commits

Reviewing files that changed from the base of the PR and between 1b1d7d9 and 7f4de36.

📒 Files selected for processing (1)
  • tests/ci-workflows.test.ts

📝 Walkthrough

Walkthrough

The status-event resolver validates commit-to-PR associations, falls back to live open-PR head-SHA matching, and fails closed for ambiguous or failed lookups. Tests execute the workflow resolver and verify outputs, diagnostics, and API calls.

Changes

Status-event PR resolution

Layer / File(s) Summary
Association and head-SHA resolution
.github/workflows/enforce-pr-target.yml
The resolver checks open PRs associated with the commit SHA. If the result is empty or ambiguous, it lists open PRs and selects only a unique matching head SHA.
Resolver validation and output capture
tests/ci-workflows.test.ts, tests/helpers/enforce-pr-target-harness.ts
runResolver executes the inline workflow script. Tests cover stale indexes, fallback matches, ambiguous or missing matches, fresh associations, lookup failures, diagnostics, and ordered core.setOutput values.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant StatusEvent
  participant ResolvePR
  participant GitHubAPI
  StatusEvent->>ResolvePR: Resolve commit SHA
  ResolvePR->>GitHubAPI: Query associated PRs
  GitHubAPI-->>ResolvePR: Return association results
  alt Empty or ambiguous result
    ResolvePR->>GitHubAPI: List open PRs
    GitHubAPI-->>ResolvePR: Return live head-SHA candidates
  end
  ResolvePR-->>StatusEvent: Emit unique PR output
Loading

Possibly related PRs

Suggested reviewers: ingwannu, lidge-jun

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes reconciling PRs by head SHA when the commit-to-PR index is stale.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tests/ci-workflows.test.ts`:
- Around line 2941-2956: Add a regression test alongside “the resolver skips
when the fallback finds no unique open head match” with two openPulls entries
sharing the same head.sha as the statusSha. Run the resolver with the same
status event setup, assert result.outputs is empty, and verify it logs the
ambiguous/stale revalidation skip behavior.
- Around line 2974-2988: Update the test “the resolver fails closed when both
resolution paths error” to include “repos.listPullRequestsAssociatedWithCommit”
in failOn, causing both resolution calls to fail. Add an assertion that logs
contain the association-index warning alongside the existing “Could not list
open PRs” warning, then retain the no-output assertion.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 5cd35232-0c9f-4673-9e1f-3b58a91b8a7e

📥 Commits

Reviewing files that changed from the base of the PR and between 8ab41d3 and fbafd58.

📒 Files selected for processing (3)
  • .github/workflows/enforce-pr-target.yml
  • tests/ci-workflows.test.ts
  • tests/helpers/enforce-pr-target-harness.ts

Comment thread tests/ci-workflows.test.ts
Comment thread tests/ci-workflows.test.ts

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tests/ci-workflows.test.ts`:
- Around line 2958-2975: Update the test “the resolver fails closed when two
open PRs share the head SHA” to assert that the fallback lookup was invoked via
the harness’s callsTo recording, specifically verifying the expected pulls.list
call and its evaluation of both matching PRs. Keep the existing empty-output and
ambiguous/stale log assertions unchanged.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: f8b3c10d-643f-4930-9f83-3da00f80e2e1

📥 Commits

Reviewing files that changed from the base of the PR and between fbafd58 and 0426b67.

📒 Files selected for processing (1)
  • tests/ci-workflows.test.ts

Comment thread tests/ci-workflows.test.ts
Wibias added 3 commits August 11, 2026 04:51
The resolve-pr job mapped a trusted CodeRabbit status SHA back to a PR via
the commit-to-PR association index. That index can lag a fresh head push
(seen on PR lidge-jun#1441), returning zero matches for a genuine current head, so
revalidation was silently skipped and new unresolved findings never
re-drafted the PR.

When the index yields no unique match, fall back to reconciling directly
against the live open-PR list by head.sha — the same authoritative identity
the write gate uses. Resolution still requires exactly one open match, so
ambiguity remains fail-closed. The fallback is a read and stays within the
resolver's pull-requests:read permission.

Add behavioural harness tests for the resolver: empty-index fallback,
no-match skip, fresh-index direct resolve, and fail-closed on error.
Address CodeRabbit feedback on the resolver tests:

- Add a regression test for the ambiguous case: two open PRs sharing the
  same head SHA must fail closed (no pull-number output), instead of only
  covering zero and one matches.
- Correct the fail-closed test so both resolution calls reject. It
  previously only failed pulls.list, so the association-index error path
  was never exercised; assert both warning messages now.
Address CodeRabbit feedback on the ambiguous fallback test: assert that the
resolver actually consults the live open-PR list (one pulls.list call with
the open-state filter) so the test cannot pass without the head-SHA
reconciliation path. The empty-output and ambiguous/stale log assertions
are unchanged.
@Wibias
Wibias force-pushed the ci/resolve-pr-fallback branch from 0426b67 to 1b1d7d9 Compare August 11, 2026 02:52
The ambiguous-head regression (two open PRs sharing the same head.sha) only
asserted empty output and the skip log. Without a pulls.list assertion it
would pass even if the head-SHA fallback were removed, because the empty
association index by itself already causes the skip.

Assert the live fallback ran: exactly one pulls.list call with the
open-state filter, alongside the retained empty-output and skip-log
assertions. The neighbouring zero-match test keeps its own independent
fallback assertion.
@Wibias
Wibias merged commit 7779c05 into lidge-jun:dev Aug 11, 2026
64 of 71 checks passed
@Wibias
Wibias deleted the ci/resolve-pr-fallback branch August 11, 2026 04:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant