name: Check PR Target Branch on: pull_request_target: types: [opened, edited, reopened, synchronize] concurrency: group: check-pr-target-${{ github.event.pull_request.number }} cancel-in-progress: true permissions: pull-requests: write jobs: check-target: runs-on: ubuntu-latest steps: - name: Reject PR targeting staged uses: actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b # v7.1.0 with: script: | 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]'; 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 === 'staged') { if (latestBotState !== 'CHANGES_REQUESTED') { const requestChangesBody = [ '⚠️ **This PR targets `staged`, but PRs should target `main`.**', '', 'The `staged` branch is no longer the contributor branch.', 'Please change the base branch to `main`.', '', '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 main`' ].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 `staged`.' ].join('\n'); await github.rest.pulls.createReview({ owner, repo, pull_number: pullNumber, event: 'APPROVE', body: approveBody }); }