Bryan Thompson 6a9addedcc
ci(validate): match vendored plugins/*/ + external_plugins/*/ manifest and content paths (#5424)
The one-level patterns (*/.claude-plugin/** etc.) never match the vendored
two-level layout because * does not cross /, so a PR touching only
plugins/<name>/.claude-plugin/plugin.json never fires the required validate
check and blocks forever (PR #5416). Same per-level spell-out the filter
already uses for plugins/*/README.md and assets.
2026-08-18 16:16:05 +00:00

83 lines
3.8 KiB
YAML

name: Validate Plugins
on:
pull_request:
paths:
- '.claude-plugin/**'
- '*/.claude-plugin/**'
- '*/agents/**'
- '*/skills/**'
- '*/commands/**'
# Vendored plugins live TWO levels deep (plugins/<name>/, external_plugins/<name>/),
# and `*` doesn't cross a `/` — so the one-level patterns above never match them.
# Without these, a PR touching only e.g. plugins/<name>/.claude-plugin/plugin.json
# (a manifest version bump) fires nothing and the required `validate` check sits
# "Expected — Waiting for status to be reported" forever (PR #5416 hit this; same
# per-level spell-out as the README/assets entries below).
- 'plugins/*/.claude-plugin/**'
- 'plugins/*/agents/**'
- 'plugins/*/skills/**'
- 'plugins/*/commands/**'
- 'external_plugins/*/.claude-plugin/**'
- 'external_plugins/*/agents/**'
- 'external_plugins/*/skills/**'
- 'external_plugins/*/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/**'
# Same rationale for the scan policy prompt: a policy-only PR (.github/policy/**)
# touches none of the plugin paths above, so validate would never trigger via
# pull_request and the required check would sit "Expected" forever (a dispatch
# check run isn't associated with the PR, so it can't satisfy the gate either).
- '.github/policy/**'
# Same again for the bump-tracking ledger: a PR that only edits
# .github/bump-tracking.json (e.g. enrolling slugs in releases-only
# tracking) matches nothing above, so the required check sits
# "Expected" forever and even a dispatched validate run on the PR
# head can't satisfy the gate (it only counts pull_request suites).
- '.github/bump-tracking.json'
# And once more for a plugin's own docs: a PR that only edits a README or
# adds a screenshot matches nothing above, so the required check never
# reports and the PR can't be merged. Spelled out per level because `*`
# doesn't cross a `/` — plugins live at plugins/<name>/, so `*/README.md`
# would not match one.
- 'plugins/*/README.md'
- 'plugins/*/assets/**'
- 'external_plugins/*/README.md'
- 'external_plugins/*/assets/**'
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
- 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