mirror of
https://github.com/anthropics/claude-plugins-official.git
synced 2026-05-12 15:35:55 +00:00
Scan Plugins is meant to gate every change to marketplace.json, but two gaps made that unenforceable: 1. The bump workflow opens PRs with GITHUB_TOKEN, which GitHub exempts from on:pull_request triggers. Weekly bump PRs (e.g. #1809) get no scan check at all. 2. The workflow had a paths filter, so a required-check ruleset for `scan` would block every PR that doesn't touch marketplace.json (no check run = pending forever). Fixes: scan-plugins.yml - Drop the paths filter; replace with a step-level `git diff --quiet` early-exit on the same paths. The check now reports on every PR, which makes it safe to require. - Fail closed when ANTHROPIC_API_KEY is unset and a scan is needed. The shared action no-ops gracefully in that case (right default for community repos), but a required check that silently does nothing is a rubber stamp. bump-plugin-shas.yml - After the action opens the bump PR, `gh workflow run scan-plugins.yml --ref bump/plugin-shas`. workflow_dispatch is exempt from the GITHUB_TOKEN recursion guard, and the resulting check run lands on the branch HEAD (= PR head), so it satisfies the required check. - Add `actions: write` so the dispatch is allowed. Follow-up: add a repo ruleset on main requiring the `scan` check (integration: github-actions) once this merges.
74 lines
2.7 KiB
YAML
74 lines
2.7 KiB
YAML
name: Scan Plugins
|
|
|
|
# Claude policy scan of changed external marketplace entries.
|
|
#
|
|
# `scan` is a required status check on main. A path-filtered workflow never
|
|
# reports a check run when its paths don't match, which would leave unrelated
|
|
# PRs blocked forever — so this workflow runs on every PR and skips the heavy
|
|
# scan setup at the step level when nothing scan-relevant changed. The check
|
|
# always reports.
|
|
|
|
on:
|
|
pull_request:
|
|
workflow_dispatch:
|
|
inputs:
|
|
scan_all:
|
|
description: Scan every external entry (full re-review). Slow.
|
|
type: boolean
|
|
default: false
|
|
|
|
permissions:
|
|
contents: read
|
|
|
|
jobs:
|
|
scan:
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 360
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
with:
|
|
fetch-depth: 0
|
|
|
|
# Same paths the workflow-level filter used to gate on. workflow_dispatch
|
|
# always runs the scan (no PR diff to inspect).
|
|
- name: Check for scan-relevant changes
|
|
id: changes
|
|
env:
|
|
EVENT_NAME: ${{ github.event_name }}
|
|
BASE_SHA: ${{ github.event.pull_request.base.sha }}
|
|
run: |
|
|
if [[ "$EVENT_NAME" == "workflow_dispatch" ]]; then
|
|
echo "relevant=true" >> "$GITHUB_OUTPUT"
|
|
exit 0
|
|
fi
|
|
if git diff --quiet "$BASE_SHA" HEAD -- .claude-plugin/marketplace.json .github/policy/; then
|
|
echo "relevant=false" >> "$GITHUB_OUTPUT"
|
|
echo "::notice::No changes to marketplace.json or policy/ — skipping policy scan."
|
|
else
|
|
echo "relevant=true" >> "$GITHUB_OUTPUT"
|
|
fi
|
|
|
|
# The shared action no-ops gracefully when ANTHROPIC_API_KEY is unset
|
|
# (sensible default for community repos). Here `scan` is a required
|
|
# check, so a silent no-op would make it a rubber stamp — fail closed.
|
|
- name: Require ANTHROPIC_API_KEY when a scan is needed
|
|
if: steps.changes.outputs.relevant == 'true'
|
|
env:
|
|
API_KEY_SET: ${{ secrets.ANTHROPIC_API_KEY != '' }}
|
|
run: |
|
|
if [[ "$API_KEY_SET" != "true" ]]; then
|
|
echo "::error::ANTHROPIC_API_KEY is not configured; refusing to skip a required policy scan."
|
|
exit 1
|
|
fi
|
|
|
|
# Blocking: policy failures fail the job. Loosen by removing
|
|
# fail-on-findings if the false-positive rate is too high.
|
|
- if: steps.changes.outputs.relevant == 'true'
|
|
uses: anthropics/claude-plugins-community/.github/actions/scan-plugins@b277757588871fe55b2620de8c6dfda470e2e9d8
|
|
with:
|
|
anthropic-api-key: ${{ secrets.ANTHROPIC_API_KEY }}
|
|
policy-prompt: .github/policy/prompt.md
|
|
fail-on-findings: "true"
|
|
scan-all-external: ${{ inputs.scan_all || 'false' }}
|
|
claude-cli-version: latest
|