Skip to content

Commit 1d74cc0

Browse files
mydeaclaude
andauthored
ref(ci): Skip PR review reminders for changes-requested PRs (#21526)
## Summary Adjusts the PR review-reminder job (`scripts/pr-review-reminder.mjs`) so it stops pinging reviewers on PRs that are blocked on the author. - **Draft PRs** are **already** ignored (`if (pr.draft) continue;`) — no change needed, documented for clarity. - **New:** skip PRs that have an **outstanding "changes requested"** review. In that state the ball is in the author's court, so nagging the reviewers is just noise. This mirrors the existing "skip if already approved" guard. ### Handling re-requests correctly A change-request only suppresses reminders while it's still outstanding. When the author addresses the feedback and **re-requests** a review, that reviewer reappears in `listRequestedReviewers` (the pending list), which supersedes their earlier change-request — so we ignore change-requests from currently-pending reviewers and they keep getting reminded. Dismissed reviews report state `DISMISSED` (not `CHANGES_REQUESTED`), so they don't count either. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 5da0cc9 commit 1d74cc0

1 file changed

Lines changed: 21 additions & 1 deletion

File tree

scripts/pr-review-reminder.mjs

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@
55
* responded within 2 business days. Re-nags every 2 business days thereafter
66
* until the review is submitted (or the request is removed).
77
*
8+
* PRs are skipped (no reminder) when they are drafts, opened by a bot, already
9+
* approved, or have an outstanding "changes requested" review (the PR is then
10+
* waiting on the author, not the reviewers).
11+
*
812
* @mentions are narrowed as follows:
913
* - Individual users: not [outside collaborators](https://docs.github.com/en/organizations/managing-outside-collaborators)
1014
* on this repo (via `repos.listCollaborators` with `affiliation: outside` — repo-scoped, no extra token).
@@ -179,16 +183,32 @@ export default async function run({ github, context, core }) {
179183
const pendingTeams = requested.teams; // team reviewers
180184
if (pendingReviewers.length === 0 && pendingTeams.length === 0) continue;
181185

182-
// Skip if the PR already has at least one approval — no need to nudge remaining reviewers
183186
const reviews = await github.paginate(github.rest.pulls.listReviews, {
184187
owner,
185188
repo,
186189
pull_number: pr.number,
187190
per_page: 100,
188191
});
192+
193+
// Skip if the PR already has at least one approval — no need to nudge remaining reviewers.
189194
const hasApproval = reviews.some(r => r.state === 'APPROVED');
190195
if (hasApproval) continue;
191196

197+
// Skip if any reviewer has an *outstanding* "changes requested" review — the ball is then in
198+
// the author's court, not the reviewers', so nagging the reviewers is noise.
199+
//
200+
// A reviewer who is re-requested after requesting changes reappears in listRequestedReviewers
201+
// (i.e. is back in `pendingReviewers`). Their earlier change-request is superseded by that new
202+
// pending request, so it must NOT suppress reminders — otherwise we'd never nudge a reviewer
203+
// the author has explicitly asked to take another look. We therefore ignore change-requests
204+
// from currently-pending reviewers. (Dismissed reviews report state `DISMISSED`, so they no
205+
// longer count either.)
206+
const pendingReviewerLogins = new Set(pendingReviewers.map(u => u.login));
207+
const hasOutstandingChangesRequested = reviews.some(
208+
r => r.state === 'CHANGES_REQUESTED' && !pendingReviewerLogins.has(r.user?.login),
209+
);
210+
if (hasOutstandingChangesRequested) continue;
211+
192212
// Fetch the PR timeline to determine when each review was (last) requested
193213
const timeline = await github.paginate(github.rest.issues.listEventsForTimeline, {
194214
owner,

0 commit comments

Comments
 (0)