Skip to content

ci: comment-cop should scan the live base...head compare, not the PR's cached file list - #38127

Open
robobun wants to merge 1 commit into
mainfrom
farm/b57b0ca8/comment-cop-live-compare
Open

ci: comment-cop should scan the live base...head compare, not the PR's cached file list#38127
robobun wants to merge 1 commit into
mainfrom
farm/b57b0ca8/comment-cop-live-compare

Conversation

@robobun

@robobun robobun commented Aug 13, 2026

Copy link
Copy Markdown
Collaborator

What does this PR do?

Problem

Fix

  • Take the diff from repos.compareCommitsWithBasehead with base.ref...head.sha. GitHub computes that from the current merge base at request time, so it is the PR's actual diff no matter what the PR's cached diff says; the file entries have the same shape (filename, status, patch) as pulls.listFiles, so the parser and the dedup keys are unchanged. Requested with per_page: 1: the changed files all come on the first page (at most 300), per_page only pages the commit list.
  • Post at most 25 new comments per run (MAX_COMMENTS_PER_RUN), with a warning annotation when the cap is hit, so a run's write volume is bounded by design instead of by the job timeout. Groups left over are still in the diff on the next push and get posted then (dedup is per group, unchanged). Of about 30 claude PRs I scanned with the new script, all but one have 12 or fewer groups in their real diff; the exception, watcher(windows): watch workspace packages outside the project root #35596, has 40 (33 of them in one file) and would get 25 on the first run and the other 15 on the push after.
  • Since presentKeys now comes from the real diff, the existing auto-resolve step identifies the bogus threads as stale (240 on fetch: reject network errors as TypeError('fetch failed' / 'terminated') with the system error as cause #35988) and resolves them once ci: use a PAT to resolve stale comment-cop review threads #36959 gives it a token that can.
  • Log the file count and merge base of the compare so the next incident of this kind is visible in the run log.

How did you verify your code works?

The workflow runs on pull_request_target from the base branch, so CI on this PR does not exercise it. I dry-ran the embedded script (extracted from the YAML, real GitHub reads, createReviewComment and the resolve mutation recorded instead of sent) against live PRs:

Does not overlap with #37948 (which groups count as a comment) or #36959 (token used to resolve threads); both touch other parts of the same script.

Per-PR audit of existing Comment Cop threads against each PR's live compare
PR #35635: cop_comments=174 on_files_outside_live_diff=172 | pr.changed_files=6    live_compare_files=6
PR #35708: cop_comments=155 on_files_outside_live_diff=154 | pr.changed_files=2    live_compare_files=2
PR #36713: cop_comments=126 on_files_outside_live_diff=123 | pr.changed_files=1946 live_compare_files=11
PR #35596: cop_comments=70  on_files_outside_live_diff=65  | pr.changed_files=8    live_compare_files=8
PR #36956: cop_comments=64  on_files_outside_live_diff=59  | pr.changed_files=21   live_compare_files=21
PR #33632: cop_comments=31  on_files_outside_live_diff=26  | pr.changed_files=10   live_compare_files=10
PR #36534: cop_comments=25  on_files_outside_live_diff=20  | pr.changed_files=9    live_compare_files=9
PR #32435: cop_comments=24  on_files_outside_live_diff=20  | pr.changed_files=13   live_compare_files=13
PR #28531: cop_comments=21  on_files_outside_live_diff=14  | pr.changed_files=11   live_compare_files=11
PR #35988: cop_comments=245 on_files_outside_live_diff=241 | pr.changed_files=3133 live_compare_files=20

For #35635, #35708 and #36713, 43 of 45, 53 of 54 and 37 of 40 of the commented-on paths were never touched by any non-merge commit on the branch (git log --no-merges --name-only origin/main..<head>), and the threads were posted in one burst per push lasting until the 5 minute timeout (for example #35635: 160 threads between 03:08 and 03:13 UTC on Aug 13, right after a rebase). pr.changed_files for most of these has since been recomputed to the right number; the threads were posted while it was not.

comment-cop took its file list from pulls.listFiles. Right after a rebase
or a merge from main, that list can still be relative to the base the PR
was opened against, so it contains every file main has touched since then
and the workflow flags comments the PR never added. It posted one review
comment per group with no bound, so each such run kept posting until the
5 minute job timeout cancelled it (about 120 comments per push).

Take the diff from repos.compareCommitsWithBasehead(base.ref...head.sha),
which GitHub computes from the current merge base at request time, and
post at most 25 new comments per run, logging a warning when capped.
@robobun

robobun commented Aug 13, 2026

Copy link
Copy Markdown
Collaborator Author

Status: reproduced and fixed.

@coderabbitai

coderabbitai Bot commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

@robobun, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 4 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 72410478-f489-4d16-a573-cfdeb58d2033

📥 Commits

Reviewing files that changed from the base of the PR and between b7a0431 and 3259e6f.

📒 Files selected for processing (1)
  • .github/workflows/comment-cop.yml

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

@claude claude 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.

LGTM — targeted CI tooling fix that swaps the stale PR file cache for a live compare and caps per-run posts.

What was reviewed:

  • compareCommitsWithBasehead response shape (files[].filename/status/patch) matches what the existing parser and dedup key consume, so downstream logic is unchanged.
  • Fork-PR head SHAs are reachable in the base repo via refs/pull/N/head, so the compare against oven-sh/bun resolves them; base refs containing / are path-encoded by octokit.
  • per_page: 1 only pages the commit list; the ≤300 files all arrive on the first page, and the 300-file ceiling is acceptable for a best-effort lint on claude-labeled PRs.
  • The .slice(0, MAX_COMMENTS_PER_RUN) cap composes correctly with the existing content-hash dedup, so overflow groups are picked up on the next push rather than lost.
Extended reasoning...

Overview

Single-file change to .github/workflows/comment-cop.yml, the internal bot that flags multi-line code comments on claude-labeled PRs. Two functional edits: (1) source the changed-file list from repos.compareCommitsWithBasehead(${base.ref}...${head.sha}) instead of pulls.listFiles, because the latter can return a stale, massively inflated diff right after a rebase/merge-from-main; (2) cap new review comments to 25 per run with a core.warning when truncating. A diagnostic core.info line logs the compare's file count and merge base.

Security risks

None introduced. The workflow already runs on pull_request_target with pull-requests: write and never checks out PR code. The only new input read from the event payload is base.ref, which is controlled by the base repo, not the PR author. No shell interpolation, no new tokens, no widened permissions.

Level of scrutiny

Low. This is repo-internal CI tooling with a bounded, reversible effect (posting/resolving review comments). The failure mode being fixed is comment spam; the worst case for the new code is under-posting (300-file compare ceiling, 25-comment cap) or a failed API call, both of which degrade to "fewer nag comments" rather than anything user-facing or build-affecting. It cannot be exercised by this PR's own CI (pull_request_target runs base-branch code), and the PR description documents dry-runs against several live PRs — including one with a currently-stale cached diff — showing identical output on accurate PRs and correct output on the pathological ones.

Other factors

The response-shape compatibility (filename, status, patch) means groupsFromPatch, keyFor, and the auto-resolve logic are untouched and continue to work; compare.files ?? [] guards the one field that can be absent. The 25-per-run cap interacts safely with the existing seenKeys dedup: unposted groups remain in the diff and are posted on the next synchronize. No prior reviewer comments to address; the bug-hunting pass found nothing.

@robobun

robobun commented Aug 13, 2026

Copy link
Copy Markdown
Collaborator Author
Updated 3:05 AM PT - Aug 13th, 2026

@robobun, your commit 3259e6f is building: #94450

@robobun

robobun commented Aug 13, 2026

Copy link
Copy Markdown
Collaborator Author
Updated 3:05 AM PT - Aug 13th, 2026

@robobun, your commit 3259e6f has some failures in Build #94450 (All Failures)


🧪   To try this PR locally:

bunx bun-pr 38127

That installs a local version of the PR into your bun-38127 executable, so you can run:

bun-38127 --bun

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants