name: ci on: push: branches: [main] pull_request: workflow_dispatch: permissions: contents: read jobs: test: name: test (node ${{ matrix.node }}) runs-on: ubuntu-latest strategy: fail-fast: false matrix: # The plugin uses top-level `await`, so the floor is real, not cosmetic. node: ['22.19.0', '24'] steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: ${{ matrix.node }} - name: Dependency install must not be required # The release is dependency-free by design: under the documented `link:` # install there is no node_modules at all. This step fails loudly if that # ever stops being true, so CI never silently depends on an install. run: | if [ -d node_modules ]; then echo "node_modules present in a fresh checkout -- unexpected"; exit 1 fi echo "clean checkout: no node_modules, as expected" - name: Detector + degeneracy + plugin test suite run: node --test test/detector.test.mjs test/degeneracy.test.mjs test/plugin.test.mjs - name: Host contract regression (the cordis schema.validate crash guard) run: node tools/verify-cordis-contract.mjs - name: Threshold calibration must still separate loops and floods from clean corpora run: node tools/calibrate.mjs package: name: package contents runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: '24' - name: npm pack must succeed and include the runtime files run: | npm pack --dry-run 2>&1 | tee pack.txt for f in lib/index.js lib/detector.js lib/degeneracy.js lib/schema-fallback.js \ cordis.patch.yml dsh.plugin.json README.md LICENSE; do grep -q "$f" pack.txt || { echo "MISSING from package: $f"; exit 1; } done echo "package contents verified" syntax: name: syntax runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: '24' - run: | for f in lib/*.js test/*.mjs tools/*.mjs; do node --check "$f" || exit 1 done echo "all modules parse"