| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364 |
- name: Close External PRs
- on:
- pull_request_target:
- types: [opened]
- permissions:
- pull-requests: write
- issues: write
- contents: read
- jobs:
- check-membership:
- if: vars.DISABLE_EXTERNAL_PR_CHECK != 'true'
- runs-on: ubuntu-latest
- steps:
- # pull_request_target: checks out the BASE repo (trusted), so the allowlist + shared
- # script below are this repo's versions, never the fork's.
- - uses: actions/checkout@v4
- - name: Close PR unless author is a member or the PR is an in-scope external contribution
- uses: actions/github-script@v7
- with:
- script: |
- const author = context.payload.pull_request.user.login;
- const { data } = await github.rest.repos.getCollaboratorPermissionLevel({
- owner: context.repo.owner,
- repo: context.repo.repo,
- username: author
- });
- if (['admin', 'write'].includes(data.permission)) {
- console.log(`${author} has ${data.permission} access, allowing PR`);
- return;
- }
- // Non-member: allow the PR to stay open ONLY if it is an in-scope external
- // contribution — it adds marketplace.json entries whose source repo ALREADY backs
- // a live plugin here, and changes nothing else. (No maintained allowlist: the set
- // of allowed repos is derived from the live marketplace.) This grants only the
- // right to open a reviewable PR; the External PR Scope Guard required check and a
- // maintainer approval still gate the merge.
- const { evaluate } = require(`${process.env.GITHUB_WORKSPACE}/.github/scripts/external-pr-scope.js`);
- const result = await evaluate({ github, context });
- if (result.ok && result.added.length > 0) {
- console.log(`In-scope external contribution (adds: ${result.added.join(', ')}) — allowing PR.`);
- return;
- }
- console.log(`Closing PR from ${author}: ${result.problems.join('; ') || 'out of scope'}`);
- await github.rest.issues.createComment({
- owner: context.repo.owner,
- repo: context.repo.repo,
- issue_number: context.payload.pull_request.number,
- body: `Thanks for your interest! This repo only accepts contributions from Anthropic team members. If you'd like to submit a plugin to the marketplace, please submit your plugin [here](https://clau.de/plugin-directory-submission).`
- });
- await github.rest.pulls.update({
- owner: context.repo.owner,
- repo: context.repo.repo,
- pull_number: context.payload.pull_request.number,
- state: 'closed'
- });
|