Files
get-shit-done/.github/workflows/test.yml
Tom Boucher 81f9534b5a feat(adr-0002): command contract validation module + prose @-ref cleanup + workflow extraction
ADR-0002: commands/gsd/*.md contract now enforced at two layers:

LINT (scripts/lint-command-contract.cjs — new CI step):
- name: present, starts with gsd: or gsd-
- description: non-empty
- allowed-tools: non-empty, all entries canonical
- execution_context @-refs: resolve on disk, no trailing prose on same line
- handles both @~/ and $HOME/ path prefixes

TEST (tests/command-contract.test.cjs — 361 assertions):
- Behavioral contract for all 65 command files
- Replaces scattered coverage in enh-2790 + bug-3135
- Per-command per-rule test — one failure names the exact file + rule

CI (.github/workflows/test.yml):
- 'Lint — command contract (ADR-0002)' step added to lint-tests job

PROSE @-REF CLEANUP (39 command files, ~900 tokens/invocation recovered):
- Removed redundant @~/.claude/get-shit-done/... paths from <process> prose
- execution_context block is now the single authoritative load declaration
- Routing commands (sketch, spike, update, pause-work, etc.) keep routing
  instructions; only the inert path token is stripped

WORKFLOW EXTRACTION (debug.md + thread.md, ~15,000 chars / ~3,750 tokens):
- get-shit-done/workflows/debug.md: full process extracted from commands/gsd/debug.md
- get-shit-done/workflows/thread.md: full process extracted from commands/gsd/thread.md
- Command files reduced to frontmatter + objective + execution_context + context
- debug.md: 9,603 → 1,703 chars; thread.md: 7,868 → 585 chars

RENAME:
- get-shit-done/workflows/extract_learnings.md → extract-learnings.md
  (aligns with hyphen convention of all other workflow files)

DOCS:
- docs/INVENTORY.md: count 85→87, new rows, rename row, fix add-todo --backlog attribution
- docs/INVENTORY-MANIFEST.json: +debug.md +thread.md +extract-learnings.md -extract_learnings.md

Closes ADR-0002 implementation.
2026-05-05 15:18:13 -04:00

109 lines
3.8 KiB
YAML

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