From 3e4cc87e91b7e07457fa2dbbbcb01ace43363e9a Mon Sep 17 00:00:00 2001 From: Aaron Powell Date: Thu, 11 Jun 2026 19:21:47 -0700 Subject: [PATCH] fix: auto-approve bot review when PR base is changed off main (#1971) * fix: reset bot review when PR base is changed off main The check-pr-target workflow only ran on 'opened' events targeting main, so it never re-ran after a submitter edited the base branch to 'staged'. The REQUEST_CHANGES review was left in place, blocking merge and requiring a manual maintainer override. Changes: - Broaden trigger to also fire on edited, reopened, and synchronize events, and add 'staged' to the branches filter so the workflow runs after a base-branch edit. - Before posting REQUEST_CHANGES, check whether the bot already has an active CHANGES_REQUESTED review to avoid duplicate reviews. - After a base-branch edit: if the PR no longer targets main and the bot's latest review state is CHANGES_REQUESTED, post an APPROVE review to clear the block automatically. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix: rerun PR target check for any base branch Co-authored-by: aaronpowell <434140+aaronpowell@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: aaronpowell <434140+aaronpowell@users.noreply.github.com> --- .github/workflows/check-pr-target.yml | 79 +++++++++++++++++++++------ 1 file changed, 62 insertions(+), 17 deletions(-) diff --git a/.github/workflows/check-pr-target.yml b/.github/workflows/check-pr-target.yml index 05f24fa7..058e6da1 100644 --- a/.github/workflows/check-pr-target.yml +++ b/.github/workflows/check-pr-target.yml @@ -2,8 +2,11 @@ name: Check PR Target Branch on: pull_request_target: - branches: [main] - types: [opened] + types: [opened, edited, reopened, synchronize] + +concurrency: + group: check-pr-target-${{ github.event.pull_request.number }} + cancel-in-progress: true permissions: pull-requests: write @@ -16,20 +19,62 @@ jobs: uses: actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b # v7.1.0 with: script: | - const body = [ - '⚠️ **This PR targets `main`, but PRs should target `staged`.**', - '', - 'The `main` branch is auto-published from `staged` and should not receive direct PRs.', - 'Please close this PR and re-open it against the `staged` branch.', - '', - 'You can change the base branch using the **Edit** button at the top of this PR,', - 'or run: `gh pr edit ${{ github.event.pull_request.number }} --base staged`' - ].join('\n'); + const pull = context.payload.pull_request; + const owner = context.repo.owner; + const repo = context.repo.repo; + const pullNumber = context.issue.number; + const botLogin = 'github-actions[bot]'; - await github.rest.pulls.createReview({ - owner: context.repo.owner, - repo: context.repo.repo, - pull_number: context.issue.number, - event: 'REQUEST_CHANGES', - body + const { data: reviews } = await github.rest.pulls.listReviews({ + owner, + repo, + pull_number: pullNumber, + per_page: 100 }); + + const latestBotReview = reviews + .filter((review) => review.user?.login === botLogin) + .sort((a, b) => new Date(a.submitted_at ?? a.created_at) - new Date(b.submitted_at ?? b.created_at)) + .at(-1); + + const latestBotState = latestBotReview?.state; + + if (pull.base.ref === 'main') { + if (latestBotState !== 'CHANGES_REQUESTED') { + const requestChangesBody = [ + '⚠️ **This PR targets `main`, but PRs should target `staged`.**', + '', + 'The `main` branch is auto-published from `staged` and should not receive direct PRs.', + 'Please close this PR and re-open it against the `staged` branch.', + '', + 'You can change the base branch using the **Edit** button at the top of this PR,', + 'or run: `gh pr edit ${{ github.event.pull_request.number }} --base staged`' + ].join('\n'); + + await github.rest.pulls.createReview({ + owner, + repo, + pull_number: pullNumber, + event: 'REQUEST_CHANGES', + body: requestChangesBody + }); + } + + return; + } + + if (latestBotState === 'CHANGES_REQUESTED') { + const approveBody = [ + '✅ Base branch is now set correctly.', + '', + 'Removing the prior block because this PR no longer targets `main`.' + ].join('\n'); + + await github.rest.pulls.createReview({ + owner, + repo, + pull_number: pullNumber, + event: 'APPROVE', + body: approveBody + }); + }