name: Tests on: push: branches: - main - 'release/**' - 'hotfix/**' pull_request: branches: - main workflow_dispatch: concurrency: group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} cancel-in-progress: true jobs: # Static lint: no source-grep tests in the test suite. # Runs once (not per matrix node version) since it is a file-content check. lint-tests: runs-on: ubuntu-latest timeout-minutes: 2 steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Set up Node.js uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 with: node-version: 24 - name: Lint — no source-grep tests shell: bash run: node scripts/lint-no-source-grep.cjs - name: Lint — command contract (ADR-0002) shell: bash run: node scripts/lint-command-contract.cjs test: runs-on: ${{ matrix.os }} timeout-minutes: 10 strategy: fail-fast: true matrix: os: [ubuntu-latest] node-version: [22, 24] include: # Single macOS runner — verifies platform compatibility on the standard version - os: macos-latest node-version: 24 # Windows path/separator coverage is handled by hardcoded-paths.test.cjs # and windows-robustness.test.cjs (static analysis, runs on all platforms). # A dedicated windows-compat workflow runs on a weekly schedule. steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: # Fetch full history so we can merge origin/main for stale-base detection. fetch-depth: 0 # GitHub's `refs/pull/N/merge` is cached against the recorded merge-base. # When main advances after a PR is opened, the cache stays stale and CI # runs against the pre-advance state — hiding bugs that are already fixed # on trunk and surfacing type errors that were introduced and then patched # on main in between. Explicitly merge current origin/main here so tests # always run against the latest trunk. - name: Rebase check — merge origin/main into PR head if: github.event_name == 'pull_request' shell: bash run: | set -euo pipefail git config user.email "ci@gsd-build" git config user.name "CI Rebase Check" git fetch origin main if ! git merge --no-edit --no-ff origin/main; then echo "::error::This PR cannot cleanly merge origin/main. Rebase your branch onto current main and push again." echo "::error::Conflicting files:" git diff --name-only --diff-filter=U git merge --abort exit 1 fi - name: Set up Node.js ${{ matrix.node-version }} uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 with: node-version: ${{ matrix.node-version }} cache: 'npm' - name: Install dependencies run: npm ci - name: Build SDK dist (required by installer) run: npm run build:sdk # Seam contract gate: keep manifest -> generated aliases -> registry/CJS adapters aligned. # Run once per workflow on the primary Linux node to avoid redundant matrix cost. - name: SDK seam coverage tests if: matrix.os == 'ubuntu-latest' && matrix.node-version == 24 shell: bash run: cd sdk && npx vitest run src/query/command-seam-coverage.test.ts - name: SDK generated alias artifact drift check if: matrix.os == 'ubuntu-latest' && matrix.node-version == 24 shell: bash run: node sdk/scripts/check-command-aliases-fresh.mjs - name: Run tests with coverage shell: bash run: npm run test:coverage