mirror of
https://github.com/lucas-labs/claude-plugins.git
synced 2026-07-10 11:15:45 -03:00
* Exempt the bump bot from the external-PR scope guard The External PR Scope Guard (#3353) and the auto-closer both look up the PR author's collaborator permission and, for anyone who is not write/admin, require the PR to ADD marketplace.json entries (additions-only). Internal bump PRs are authored by github-actions[bot], which is not reported as a member, so a SHA-bump — a legitimate MODIFY of an existing entry — fails the guard (e.g. #3391 "modifies existing entry: astronomer-data-agents"). Add a shared isExemptAuthor() helper that exempts both org members and the repo's own automation bot, and route both workflows through it. Safe under pull_request_target: a fork PR cannot author as github-actions[bot] (only the org's own GITHUB_TOKEN workflow can), and the member path is still a real permission lookup. The helper also wraps getCollaboratorPermissionLevel in try/catch — previously a non-collaborator/unknown-user lookup threw and errored the job instead of falling through to scope evaluation. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Correct stale "required status check" guidance in scope-guard comments The scope guard is advisory, not a required status check — the merge gate is validate + scan + a maintainer approval. The old header told operators to add it to branch protection, which is now contra-indicated (it would block the no-approval bump-merge path). Update both workflow comments to match. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
55 lines
2.4 KiB
YAML
55 lines
2.4 KiB
YAML
name: External PR Scope Guard
|
|
|
|
# Advisory check that surfaces what a NON-MEMBER pull request may change.
|
|
# Members (write/admin) and the repo's own automation bot (bump SHA PRs) are unrestricted and
|
|
# skip this check. For a non-member PR this fails unless the PR is an in-scope external
|
|
# contribution per .github/scripts/external-pr-scope.js: it changes ONLY
|
|
# .claude-plugin/marketplace.json, the delta is additions-only (no existing entry modified or
|
|
# removed), and every ADDED entry's source.url is a repo that ALREADY backs a live plugin in
|
|
# this marketplace (the allowed set is derived from the live marketplace — there is no
|
|
# maintained allowlist).
|
|
#
|
|
# Do NOT add this job to branch protection as a required status check. The merge gate is the
|
|
# `validate` + `scan` checks plus a maintainer approval; this guard is advisory signal for the
|
|
# reviewer, not a hard gate. (Making it required would block the no-approval bump-merge path.)
|
|
#
|
|
# Security: runs on pull_request_target but checks out only the BASE repo (trusted) for the
|
|
# shared script; the head marketplace.json is fetched as DATA via the API and parsed, never executed.
|
|
|
|
on:
|
|
pull_request_target:
|
|
types: [opened, synchronize, reopened]
|
|
|
|
permissions:
|
|
contents: read
|
|
pull-requests: read
|
|
|
|
jobs:
|
|
scope-guard:
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v4 # base repo (trusted)
|
|
- uses: actions/github-script@v7
|
|
with:
|
|
script: |
|
|
const { evaluate, isExemptAuthor } = require(`${process.env.GITHUB_WORKSPACE}/.github/scripts/external-pr-scope.js`);
|
|
|
|
// Members (write/admin) and the repo's own automation bot (bump SHA PRs) are
|
|
// unrestricted; only genuinely external contributions are scope-checked.
|
|
const ex = await isExemptAuthor({ github, context });
|
|
if (ex.exempt) {
|
|
console.log(`${ex.reason} — scope guard not applicable.`);
|
|
return;
|
|
}
|
|
|
|
const result = await evaluate({ github, context });
|
|
|
|
if (!result.ok) {
|
|
core.setFailed(
|
|
`Scope guard: a non-member PR may only ADD marketplace.json entries whose source repo already backs a live plugin here.\n - ` +
|
|
result.problems.join('\n - ')
|
|
);
|
|
return;
|
|
}
|
|
console.log(`Scope guard passed: adds ${result.added.join(', ') || 'none'}, all from repos already live here.`);
|