What Does the Validate Plugins GitHub Action Do? A Complete Technical Guide
The Validate Plugins GitHub Action is a composite CI step in anthropics/claude-plugins-community that automates schema validation, security invariant checks, change detection, and reporting for Claude plugin entries.
The validate-plugins action serves as the canonical validation pipeline for the Claude plugins marketplace. Located at .github/actions/validate-plugins, this composite GitHub Action orchestrates a multi-stage workflow that ensures every plugin entry meets strict quality and security standards before publication.
Core Validation Pipeline
The action executes seven sequential stages, each implemented as a shell script in the scripts/ directory.
1. Detect Changes (00-detect-changes.sh)
The Detect changes step compares the current PR or commit against a base reference to identify what actually changed. It produces three JSON arrays:
changed-entries— marketplace entries modified in this PRchanged-external— external plugin sources that need re-validationchanged-folders— in-repo plugin folders with modifications
This selective approach avoids validating unchanged entries, significantly reducing CI runtime.
# The detection script runs automatically as step 1
bash .github/actions/validate-plugins/scripts/00-detect-changes.sh
The script assembles a temporary marketplace.json from per-file entries and writes results to changes.json for downstream consumption.
2. Validate Invariants (11-validate-invariants.sh)
The custom invariant checks (I1-I11) enforce marketplace-specific policies beyond basic schema validation. These include:
- Ordering invariants — entries must follow alphabetical or semantic ordering rules
- Naming conventions — plugin IDs and display names must match approved patterns
- SHA pinning — external sources must reference specific commit SHAs, not floating branches
- Host allow-lists — all external URLs must resolve to approved hosting domains
Configure invariant behavior using action inputs:
warn-invariants— comma-separated list of invariant IDs to treat as warningsfail-on-warnings— whentrue, warnings become hard failuresscope-errors-to-changed— only report invariant violations on modified entries
3. CLI Marketplace Validation (20-validate-cli-marketplace.sh)
This step executes claude plugin validate against the assembled marketplace.json — the upstream "source-of-truth" schema checker maintained by Anthropic. It catches:
- Missing required fields in plugin manifests
- Type mismatches against the official JSON Schema
- Invalid plugin capability declarations
4. External Plugin Validation (30-validate-cli-external.sh)
For each changed external entry (or all external entries when validate-all-external: true), the action:
- Clones the external repository
- Validates the host against
allowed-hosts - Runs
claude plugin validatewith a per-plugin timeout
This prevents supply-chain attacks by verifying external plugins at their source before marketplace inclusion.
5. Local Folder Validation (40-validate-cli-local.sh)
For in-repo plugins with .claude-plugin/plugin.json files, this step runs targeted CLI validation on each changed folder individually. Skip this with skip-local-folders: "true" when validating marketplace-only repositories.
6. Generate Report (90-report.sh)
The Report step aggregates all errors and warnings into a human-readable markdown file, exposed via the report-path output. The report includes:
- Per-entry validation status
- Invariant violation details with line references
- External plugin clone and validation logs
7. Export Results
Final outputs enable downstream workflow orchestration:
| Output | Description |
|---|---|
changed-entries |
JSON array of modified marketplace entries |
changed-external |
JSON array of changed external sources |
changed-folders |
JSON array of modified local plugin folders |
result |
"pass" or "fail" overall status |
report-path |
Path to the generated markdown report |
Action Configuration
The action is defined in .github/actions/validate-plugins/action.yml with these key inputs:
# Example: Using the action with custom configuration
- uses: ./.github/actions/validate-plugins
with:
marketplace-path: .claude-plugin/marketplace.json
entries-dir: .claude-plugin/plugins
allowed-hosts: "github.com,gitlab.com"
validate-all-external: "false"
skip-local-folders: "false"
warn-invariants: "I3,I7"
fail-on-warnings: "false"
scope-errors-to-changed: "true"
Complete Workflow Example
The canonical usage appears in .github/workflows/validate-plugins.yml:
name: Validate Plugins
on:
pull_request:
paths:
- '.claude-plugin/**'
- '.github/actions/**'
push:
branches: [main]
paths:
- '.claude-plugin/**'
- '.github/actions/**'
jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0 # Required for accurate change detection
# Optional: Run static invariant tests separately
- name: Static invariant tests
run: bash .github/actions/validate-plugins/test-invariants.sh
# Dogfood: Run the shared Validate Plugins action
- uses: ./.github/actions/validate-plugins
id: validate
with:
marketplace-path: .claude-plugin/marketplace.json
scope-errors-to-changed: "true"
# Example: Use outputs in downstream steps
- name: Process changed entries
if: steps.validate.outputs.result == 'pass'
run: |
echo "Changed: ${{ steps.validate.outputs.changed-entries }}"
Manual Debugging
Invoke individual validation scripts locally or in CI for targeted debugging:
# Validate invariants only
bash .github/actions/validate-plugins/scripts/11-validate-invariants.sh \
MARKETPLACE_PATH=.claude-plugin/marketplace.json \
ENTRIES_DIR=.claude-plugin/plugins \
BASE_REF=origin/main \
FAIL_ON_WARNINGS=false \
WARN_INVARIANTS="I3,I7"
# Validate external plugins with full scope
VALIDATE_ALL_EXTERNAL=true \
MARKETPLACE_PATH=.claude-plugin/marketplace.json \
bash .github/actions/validate-plugins/scripts/30-validate-cli-external.sh
Key Implementation Files
| File | Purpose |
|---|---|
.github/actions/validate-plugins/action.yml |
Composite action metadata and step orchestration |
scripts/00-detect-changes.sh |
Git diff parsing and change classification |
scripts/11-validate-invariants.sh |
Policy invariants I1-I11 enforcement |
scripts/20-validate-cli-marketplace.sh |
Schema validation via claude plugin validate |
scripts/30-validate-cli-external.sh |
External repo cloning and validation |
scripts/40-validate-cli-local.sh |
In-repo folder validation |
scripts/90-report.sh |
Markdown report generation |
Summary
- The Validate Plugins GitHub Action is a composite action that automates the complete Claude plugin validation lifecycle in
anthropics/claude-plugins-community. - Change detection (
00-detect-changes.sh) minimizes CI overhead by identifying only modified entries. - Invariant checks (
11-validate-invariants.sh) enforce marketplace policies beyond basic schema validation. - CLI validation runs against marketplace JSON, external repositories, and local folders with configurable timeouts and host restrictions.
- Flexible configuration via
warn-invariants,fail-on-warnings, andscope-errors-to-changedinputs lets repositories tune validation strictness. - Structured outputs (
changed-entries,result,report-path) enable downstream automation and human review.
Frequently Asked Questions
What is the difference between invariants and CLI validation?
Invariants are custom policy checks (I1-I11) defined in 11-validate-invariants.sh that enforce marketplace-specific rules like SHA pinning and alphabetical ordering. CLI validation uses the official claude plugin validate command to verify conformance against Anthropic's published JSON Schema. Invariants catch policy violations; CLI validation catches structural and type errors.
How does the action handle external plugin security?
The action validates external plugins in 30-validate-cli-external.sh by cloning each repository fresh, checking the host against an allowed-hosts allow-list, and running claude plugin validate with a per-plugin timeout. This prevents malicious modifications between marketplace review and user installation.
Can I run validation locally without GitHub Actions?
Yes. Clone the repository and execute individual scripts directly. Set required environment variables like MARKETPLACE_PATH and BASE_REF as shown in the manual debugging examples. The claude CLI must be installed and authenticated for schema validation steps to function.
What causes the action to fail versus warn?
By default, all invariant violations and schema errors fail the action. Use warn-invariants to downgrade specific invariant IDs to warnings, and fail-on-warnings: "false" to allow warnings without failing the workflow. The scope-errors-to-changed input further reduces noise by only reporting violations on entries modified in the current PR.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →