mirror of
https://github.com/anthropics/claude-plugins-official.git
synced 2026-08-21 07:47:41 -03:00
Replace the per-username allowlist with a source-org allowlist so no individual is named in the repo. A non-member PR stays open only if it adds marketplace.json entries whose source.url is under an allowlisted prefix and changes nothing else; merge still requires CI + maintainer approval. - external-pr-allowed-sources.json: flat allowed_sources prefixes (no usernames) - scripts/external-pr-scope.js: shared additions-only / allowed-source logic - close-external-prs.yml + external-pr-scope-guard.yml: both use the shared module Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
67 lines
2.8 KiB
YAML
67 lines
2.8 KiB
YAML
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 pointing at an allowlisted
|
|
// source org and changes nothing else (see .github/external-pr-allowed-sources.json).
|
|
// 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,
|
|
allowlistPath: `${process.env.GITHUB_WORKSPACE}/.github/external-pr-allowed-sources.json`,
|
|
});
|
|
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'
|
|
});
|