|
| 1 | +name: Guardrail suites |
| 2 | + |
| 3 | +# Runs every local fixture-based test suite plus the marketplace + frontmatter |
| 4 | +# validators. Release-blocking: closes F-005 (beta promotion exemption) and |
| 5 | +# codifies the 90-test safety net that v0.8.x and v0.9.0 shipped with but had |
| 6 | +# never actually run in CI. |
| 7 | +# |
| 8 | +# Each suite is a single shell script that exits non-zero on failure. The |
| 9 | +# matrix runs them in parallel for speed and so one failure doesn't mask |
| 10 | +# another. The marketplace-validate job also asserts the CLI's human-readable |
| 11 | +# "Validation failed" text, because `claude plugin validate` returns exit 0 |
| 12 | +# even when the schema rejects (caught during v0.8.1 — F-001). |
| 13 | + |
| 14 | +on: |
| 15 | + pull_request: |
| 16 | + push: |
| 17 | + branches: [main] |
| 18 | + |
| 19 | +jobs: |
| 20 | + # ---------- Static validators (Python, no Claude/Codex CLI needed) ---------- |
| 21 | + |
| 22 | + frontmatter: |
| 23 | + name: Frontmatter validator |
| 24 | + runs-on: ubuntu-latest |
| 25 | + steps: |
| 26 | + - uses: actions/checkout@v4 |
| 27 | + - uses: actions/setup-python@v5 |
| 28 | + with: |
| 29 | + python-version: '3.12' |
| 30 | + - run: python3 scripts/validate-frontmatter.py |
| 31 | + |
| 32 | + cache-discipline: |
| 33 | + name: Cache-discipline validator (strict, remediated skills) |
| 34 | + runs-on: ubuntu-latest |
| 35 | + steps: |
| 36 | + - uses: actions/checkout@v4 |
| 37 | + - uses: actions/setup-python@v5 |
| 38 | + with: |
| 39 | + python-version: '3.12' |
| 40 | + - run: | |
| 41 | + python3 scripts/validate-cache-discipline.py |
| 42 | + python3 scripts/validate-cache-discipline.py --strict \ |
| 43 | + core/skills/tdd-cycle/ \ |
| 44 | + core/skills/implementer/ \ |
| 45 | + core/skills/reviewer/ \ |
| 46 | + core/skills/verify/ |
| 47 | +
|
| 48 | + # ---------- Fixture-based suites (bash + jq, no external tools) ------------- |
| 49 | + |
| 50 | + fixtures: |
| 51 | + name: "Fixture suite: ${{ matrix.suite }}" |
| 52 | + runs-on: ubuntu-latest |
| 53 | + strategy: |
| 54 | + fail-fast: false |
| 55 | + matrix: |
| 56 | + suite: |
| 57 | + - hooks/test-filter-learnings.sh |
| 58 | + - test-deletion-guardrail/test-test-deletion-guardrail.sh |
| 59 | + - codex-install/test-install-paths.sh |
| 60 | + - cache-discipline/test-cache-discipline.sh |
| 61 | + - secrets-handling/test-secrets-handling.sh |
| 62 | + - agents-md-sync/test-agents-md-sync.sh |
| 63 | + - telemetry-jsonl/test-telemetry-jsonl.sh |
| 64 | + - security/test-prompt-injection-defense.sh |
| 65 | + - rule-parity/test-rule-parity.sh |
| 66 | + steps: |
| 67 | + - uses: actions/checkout@v4 |
| 68 | + - name: Install jq |
| 69 | + run: sudo apt-get update -qq && sudo apt-get install -y jq |
| 70 | + - name: Run tests/${{ matrix.suite }} |
| 71 | + run: bash tests/${{ matrix.suite }} |
| 72 | + |
| 73 | + # ---------- Marketplace validation ----------------------------------------- |
| 74 | + # |
| 75 | + # `claude plugin validate` exits 0 even when validation fails (discovered via |
| 76 | + # F-001). We grep the stdout for "Validation failed" to turn a silent failure |
| 77 | + # into a red CI light. |
| 78 | + |
| 79 | + marketplace-validate: |
| 80 | + name: Claude marketplace manifest |
| 81 | + runs-on: ubuntu-latest |
| 82 | + steps: |
| 83 | + - uses: actions/checkout@v4 |
| 84 | + |
| 85 | + - name: Install Claude Code CLI |
| 86 | + run: | |
| 87 | + npm install -g @anthropic-ai/claude-code || { |
| 88 | + echo "::warning::Claude CLI install failed — skipping marketplace validation." |
| 89 | + echo "SKIP=1" >> "$GITHUB_ENV" |
| 90 | + } |
| 91 | +
|
| 92 | + - name: Validate root marketplace manifest |
| 93 | + if: env.SKIP != '1' |
| 94 | + run: | |
| 95 | + set +e |
| 96 | + out=$(claude plugin validate . 2>&1) |
| 97 | + rc=$? |
| 98 | + echo "$out" |
| 99 | + if echo "$out" | grep -q "Validation failed"; then |
| 100 | + echo "::error::Root marketplace manifest validation failed" |
| 101 | + exit 1 |
| 102 | + fi |
| 103 | + exit "$rc" |
| 104 | +
|
| 105 | + - name: Validate plugin manifest |
| 106 | + if: env.SKIP != '1' |
| 107 | + run: | |
| 108 | + set +e |
| 109 | + out=$(claude plugin validate plugins/add 2>&1) |
| 110 | + rc=$? |
| 111 | + echo "$out" |
| 112 | + if echo "$out" | grep -q "Validation failed"; then |
| 113 | + echo "::error::Plugin manifest validation failed" |
| 114 | + exit 1 |
| 115 | + fi |
| 116 | + exit "$rc" |
0 commit comments