name: CI on: push: branches: [main, 'release/**'] tags: ['v*'] pull_request: branches: [main] # Prevent duplicate runs concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true # Minimal permissions permissions: contents: read jobs: test: name: Test (${{ matrix.os }}, Node ${{ matrix.node }}, ${{ matrix.pm }}) runs-on: ${{ matrix.os }} timeout-minutes: 10 strategy: fail-fast: false matrix: os: [ubuntu-latest, windows-latest, macos-latest] node: ['18.x', '20.x', '22.x'] pm: [npm, pnpm, yarn, bun] exclude: # Bun has limited Windows support - os: windows-latest pm: bun steps: - name: Checkout uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Setup Node.js ${{ matrix.node }} uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 with: node-version: ${{ matrix.node }} # Package manager setup - name: Setup pnpm if: matrix.pm == 'pnpm' && matrix.node != '18.x' uses: pnpm/action-setup@91ab88e2619ed1f46221f0ba42d1492c02baf788 # v6.0.6 with: # Keep an explicit pnpm major because this repo's packageManager is Yarn. version: 10 - name: Setup pnpm (via Corepack) if: matrix.pm == 'pnpm' && matrix.node == '18.x' shell: bash run: | corepack enable corepack prepare pnpm@9 --activate - name: Setup Yarn (via Corepack) if: matrix.pm == 'yarn' shell: bash run: | corepack enable corepack prepare yarn@stable --activate - name: Setup Bun if: matrix.pm == 'bun' uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2 # Install dependencies # COREPACK_ENABLE_STRICT=0 allows pnpm to install even though # package.json declares "packageManager": "yarn@..." - name: Install dependencies shell: bash env: COREPACK_ENABLE_STRICT: '0' npm_config_ignore_scripts: 'true' YARN_ENABLE_SCRIPTS: 'false' run: | case "${{ matrix.pm }}" in npm) npm ci --ignore-scripts ;; # pnpm v10 can fail CI on ignored native build scripts # (for example msgpackr-extract) even though this repo is Yarn-native # and pnpm is only exercised here as a compatibility lane. pnpm) pnpm install --ignore-scripts --config.strict-dep-builds=false --no-frozen-lockfile ;; # Yarn Berry (v4+) removed --ignore-engines; engine checking is no longer a core feature yarn) yarn install --mode=skip-build ;; bun) bun install --ignore-scripts ;; *) echo "Unsupported package manager: ${{ matrix.pm }}" && exit 1 ;; esac # Run tests - name: Run tests run: node tests/run-all.js env: CLAUDE_CODE_PACKAGE_MANAGER: ${{ matrix.pm }} # Upload test artifacts on failure - name: Upload test artifacts if: failure() uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: test-results-${{ matrix.os }}-node${{ matrix.node }}-${{ matrix.pm }} path: | tests/ !tests/node_modules/ validate: name: Validate Components runs-on: ubuntu-latest timeout-minutes: 5 steps: - name: Checkout uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Setup Node.js uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 with: node-version: '20.x' - name: Install validation dependencies run: npm ci --ignore-scripts - name: Validate agents run: node scripts/ci/validate-agents.js continue-on-error: false - name: Validate hooks run: node scripts/ci/validate-hooks.js continue-on-error: false - name: Validate commands run: node scripts/ci/validate-commands.js continue-on-error: false - name: Validate skills run: node scripts/ci/validate-skills.js continue-on-error: false - name: Validate install manifests run: node scripts/ci/validate-install-manifests.js continue-on-error: false - name: Validate workflow security run: node scripts/ci/validate-workflow-security.js continue-on-error: false - name: Validate rules run: node scripts/ci/validate-rules.js continue-on-error: false - name: Validate catalog counts run: node scripts/ci/catalog.js --text continue-on-error: false - name: Validate command registry run: npm run command-registry:check continue-on-error: false - name: Check unicode safety run: node scripts/ci/check-unicode-safety.js continue-on-error: false - name: Validate no personal paths run: node scripts/ci/validate-no-personal-paths.js continue-on-error: false security: name: Security Scan runs-on: ubuntu-latest timeout-minutes: 5 steps: - name: Checkout uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Setup Node.js uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 with: node-version: '20.x' - name: Install audit dependencies run: npm ci --ignore-scripts - name: Run npm audit run: | npm audit signatures npm audit --audit-level=high - name: Run supply-chain IOC scan run: npm run security:ioc-scan coverage: name: Coverage runs-on: ubuntu-latest timeout-minutes: 10 steps: - name: Checkout uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Setup Node.js uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 with: node-version: '20.x' - name: Install dependencies run: npm ci --ignore-scripts - name: Run coverage run: npm run coverage - name: Upload coverage report if: always() uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: coverage-ubuntu-node20-npm path: coverage/ lint: name: Lint runs-on: ubuntu-latest timeout-minutes: 5 steps: - name: Checkout uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Setup Node.js uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 with: node-version: '20.x' - name: Install dependencies run: npm ci --ignore-scripts - name: Run ESLint run: npx eslint scripts/**/*.js tests/**/*.js - name: Run markdownlint run: npx markdownlint "agents/**/*.md" "skills/**/*.md" "commands/**/*.md" "rules/**/*.md"