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 PR
  • changed-external — external plugin sources that need re-validation
  • changed-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 warnings
  • fail-on-warnings — when true, warnings become hard failures
  • scope-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:

  1. Clones the external repository
  2. Validates the host against allowed-hosts
  3. Runs claude plugin validate with 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, and scope-errors-to-changed inputs 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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →