fix: escape pipe in markdown table for markdownlint #7
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: CI | |
| on: | |
| push: | |
| branches: [main] | |
| 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@v4 | |
| - name: Setup Node.js ${{ matrix.node }} | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: ${{ matrix.node }} | |
| # Package manager setup | |
| - name: Setup pnpm | |
| if: matrix.pm == 'pnpm' | |
| uses: pnpm/action-setup@v4 | |
| with: | |
| version: latest | |
| - name: Setup Bun | |
| if: matrix.pm == 'bun' | |
| uses: oven-sh/setup-bun@v2 | |
| # Cache configuration | |
| - name: Get npm cache directory | |
| if: matrix.pm == 'npm' | |
| id: npm-cache-dir | |
| shell: bash | |
| run: echo "dir=$(npm config get cache)" >> $GITHUB_OUTPUT | |
| - name: Cache npm | |
| if: matrix.pm == 'npm' | |
| uses: actions/cache@v4 | |
| with: | |
| path: ${{ steps.npm-cache-dir.outputs.dir }} | |
| key: ${{ runner.os }}-node-${{ matrix.node }}-npm-${{ hashFiles('**/package-lock.json') }} | |
| restore-keys: | | |
| ${{ runner.os }}-node-${{ matrix.node }}-npm- | |
| - name: Get pnpm store directory | |
| if: matrix.pm == 'pnpm' | |
| id: pnpm-cache-dir | |
| shell: bash | |
| run: echo "dir=$(pnpm store path)" >> $GITHUB_OUTPUT | |
| - name: Cache pnpm | |
| if: matrix.pm == 'pnpm' | |
| uses: actions/cache@v4 | |
| with: | |
| path: ${{ steps.pnpm-cache-dir.outputs.dir }} | |
| key: ${{ runner.os }}-node-${{ matrix.node }}-pnpm-${{ hashFiles('**/pnpm-lock.yaml') }} | |
| restore-keys: | | |
| ${{ runner.os }}-node-${{ matrix.node }}-pnpm- | |
| - name: Get yarn cache directory | |
| if: matrix.pm == 'yarn' | |
| id: yarn-cache-dir | |
| shell: bash | |
| run: | | |
| # Try Yarn Berry first, fall back to Yarn v1 | |
| if yarn config get cacheFolder >/dev/null 2>&1; then | |
| echo "dir=$(yarn config get cacheFolder)" >> $GITHUB_OUTPUT | |
| else | |
| echo "dir=$(yarn cache dir)" >> $GITHUB_OUTPUT | |
| fi | |
| - name: Cache yarn | |
| if: matrix.pm == 'yarn' | |
| uses: actions/cache@v4 | |
| with: | |
| path: ${{ steps.yarn-cache-dir.outputs.dir }} | |
| key: ${{ runner.os }}-node-${{ matrix.node }}-yarn-${{ hashFiles('**/yarn.lock') }} | |
| restore-keys: | | |
| ${{ runner.os }}-node-${{ matrix.node }}-yarn- | |
| - name: Cache bun | |
| if: matrix.pm == 'bun' | |
| uses: actions/cache@v4 | |
| with: | |
| path: ~/.bun/install/cache | |
| key: ${{ runner.os }}-bun-${{ hashFiles('**/bun.lockb') }} | |
| restore-keys: | | |
| ${{ runner.os }}-bun- | |
| # Install dependencies | |
| - name: Install dependencies | |
| shell: bash | |
| run: | | |
| case "${{ matrix.pm }}" in | |
| npm) npm ci ;; | |
| pnpm) pnpm install ;; | |
| # --ignore-engines required for Node 18 compat with some devDependencies (e.g., markdownlint-cli) | |
| yarn) yarn install --ignore-engines ;; | |
| bun) bun install ;; | |
| *) 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@v4 | |
| 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@v4 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: '20.x' | |
| - 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 rules | |
| run: node scripts/ci/validate-rules.js | |
| continue-on-error: false | |
| security: | |
| name: Security Scan | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 5 | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: '20.x' | |
| - name: Run npm audit | |
| run: npm audit --audit-level=high | |
| continue-on-error: true # Allows PR to proceed, but marks job as failed if vulnerabilities found | |
| lint: | |
| name: Lint | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 5 | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: '20.x' | |
| - name: Install dependencies | |
| run: npm ci | |
| - name: Run ESLint | |
| run: npx eslint scripts/**/*.js tests/**/*.js | |
| - name: Run markdownlint | |
| run: npx markdownlint "agents/**/*.md" "skills/**/*.md" "commands/**/*.md" "rules/**/*.md" |