From d1c1e522600448b9ef8b20048c72f4547a4ea639 Mon Sep 17 00:00:00 2001 From: Luke Mino-Altherr Date: Wed, 27 May 2026 16:25:16 -0700 Subject: [PATCH] Accept dismissed approvals as valid reviews MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit "Dismiss stale reviews on new commits" changes APPROVED → DISMISSED when commits are pushed after approval. The review still happened, so count DISMISSED as a valid approval. Co-Authored-By: Claude Opus 4.6 (1M context) --- .github/workflows/detect-unreviewed-merge.yml | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/.github/workflows/detect-unreviewed-merge.yml b/.github/workflows/detect-unreviewed-merge.yml index ede30e6b1..c23a35b2c 100644 --- a/.github/workflows/detect-unreviewed-merge.yml +++ b/.github/workflows/detect-unreviewed-merge.yml @@ -41,24 +41,17 @@ jobs: core.info(`Found PR #${pr.number}: ${pr.title}`); - // Determine effective approval state using latest review per reviewer + // Check for approvals. DISMISSED counts because "dismiss stale reviews + // on new commits" changes APPROVED → DISMISSED when commits are pushed + // after approval — the review still happened. const reviews = await github.paginate(github.rest.pulls.listReviews, { owner, repo, pull_number: pr.number, }); - const latestByReviewer = new Map(); - for (const r of reviews) { - if (!r.user || r.state === 'COMMENTED') continue; - const prev = latestByReviewer.get(r.user.login); - if (!prev || new Date(r.submitted_at) > new Date(prev.submitted_at)) { - latestByReviewer.set(r.user.login, r); - } - } - - const hasApproval = Array.from(latestByReviewer.values()).some( - r => r.state === 'APPROVED' + const hasApproval = reviews.some( + r => r.state === 'APPROVED' || r.state === 'DISMISSED' ); if (hasApproval) { core.info('PR has an approving review — no action needed.');