name: Validate Plugins on: pull_request: paths: - '.claude-plugin/**' - '*/.claude-plugin/**' - '*/agents/**' - '*/skills/**' - '*/commands/**' # `validate` is a required status check, so a PR that touches ONLY workflow # files (e.g. an action-SHA re-pin) would otherwise never trigger validate # and sit "Expected — Waiting for status to be reported" forever (workflow_dispatch # check runs aren't associated with the PR, so they don't satisfy it). Run # validate on workflow changes too so those PRs can clear the gate in-context. - '.github/workflows/**' push: branches: [main] paths: - '.claude-plugin/**' # `validate` is a required status check on main. Bump PRs are opened with # GITHUB_TOKEN, which doesn't fire on:pull_request (recursion guard), so the # path-filtered trigger above never reports on them and the PR would be # blocked forever. The bump workflow dispatches this against each per-entry # bump branch instead; the check run lands on the branch HEAD (= PR head) # and satisfies the required check. The validate job runs unconditionally, # so a dispatch always reports. workflow_dispatch: permissions: contents: read jobs: validate: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 with: fetch-depth: 0 - name: Check for renamed plugins without renames entry run: | set -euo pipefail base="${{ github.event.pull_request.base.sha || 'origin/main' }}" # Names removed from plugins[] in this diff removed=$(comm -23 \ <(git show "$base:.claude-plugin/marketplace.json" | jq -r '.plugins[].name' | sort) \ <(jq -r '.plugins[].name' .claude-plugin/marketplace.json | sort)) [ -z "$removed" ] && { echo "No plugin names removed."; exit 0; } # Renames keys present in HEAD rename_keys=$(jq -r '.renames // {} | keys[]' .claude-plugin/marketplace.json | sort) missing=$(comm -23 <(echo "$removed" | sort) <(echo "$rename_keys")) if [ -n "$missing" ]; then echo "::error::Plugin name(s) removed without a renames entry: $missing" echo "Add to .claude-plugin/marketplace.json top-level \"renames\": {\"\": \"\"} (or null if intentionally removed)." exit 1 fi echo "All removed names have renames entries." - uses: anthropics/claude-plugins-community/.github/actions/validate-plugins@426e469f322952061102b286b378c0c9733a0934 with: marketplace-path: .claude-plugin/marketplace.json # Official curated marketplace: SHA-pin (I5) is a HARD error. # I8/I11 are warnings until the 15 known vendored-path/name issues # are cleaned up (see PR body); tighten to "I1 I3" after. warn-invariants: "I1 I3 I8 I11" claude-cli-version: latest