From 52d26bb7afa9129b0787d2035f66ec7634efeab6 Mon Sep 17 00:00:00 2001 From: Justin Stayton Date: Thu, 8 Oct 2026 05:56:08 -0400 Subject: [PATCH 1/2] Streamline CI and coverage collection Fixes VISION-4310. --- .github/workflows/ci.yml | 54 ++++++++++++++++++++++------------------ AGENTS.md | 7 +++--- 2 files changed, 34 insertions(+), 27 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0a57674..a9e1f3a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -6,52 +6,55 @@ on: - '**' workflow_dispatch: +permissions: + contents: read + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +defaults: + run: + shell: bash + jobs: lint-test: name: Lint & test runs-on: ubuntu-latest + timeout-minutes: 15 strategy: + fail-fast: false matrix: node-version: ['22.x', '24.x', '26.x'] steps: - name: Check out repository - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Set up Node.js v${{ matrix.node-version }} - uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0 + uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0 with: node-version: ${{ matrix.node-version }} cache: 'npm' - name: Install npm dependencies - run: npm install + run: npm ci - name: Run lint + if: matrix.node-version == '26.x' run: npm run lint - name: Run typecheck + if: matrix.node-version == '26.x' run: npm run typecheck - name: Run tests + if: matrix.node-version != '26.x' run: npm test - - test-coverage: - name: Test coverage - runs-on: ubuntu-latest - steps: - - name: Check out repository - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 - - name: Set up Node.js - uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0 - with: - node-version: '26.x' - cache: 'npm' - - name: Install npm dependencies - run: npm install - - name: Run tests - run: | - set -o pipefail - npm run test:coverage | tee "$RUNNER_TEMP/tests.txt" + - name: Run tests with coverage + if: matrix.node-version == '26.x' + run: npm run test:coverage | tee "$RUNNER_TEMP/tests.txt" # Reported in its own step so the summary is still written when the suite # fails, which is when the test results are most worth reading. Node # prints both its summary and the coverage report even on failure. - name: Report test results & coverage - if: ${{ !cancelled() }} + if: + ${{ !cancelled() && matrix.node-version == '26.x' && + hashFiles('coverage/lcov.info') != '' }} run: | { echo '## Tests' @@ -67,8 +70,11 @@ jobs: echo '```' } >> "$GITHUB_STEP_SUMMARY" - name: Upload coverage report - if: ${{ !cancelled() }} + if: + ${{ !cancelled() && matrix.node-version == '26.x' && + hashFiles('coverage/lcov.info') != '' }} uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: - name: coverage + name: coverage-${{ github.run_attempt }} path: coverage/ + retention-days: 14 diff --git a/AGENTS.md b/AGENTS.md index 086962b..e7ea7b2 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -9,9 +9,10 @@ code in this repository. tests live next to source as `*.test.js`). - `npm test -- --watch` — re-run tests on file change. - `npm run test:coverage` — run the suite with coverage, printing a report and - writing `coverage/lcov.info`. CI runs this in a separate job that posts the - test results and coverage report to the run summary and uploads the report as - an artifact. There is no threshold: coverage is reported, not enforced. + writing `coverage/lcov.info`. CI collects coverage during the Node 26 matrix + run, posts the test results and coverage report to the run summary, and + uploads the report as an artifact. There is no threshold: coverage is + reported, not enforced. - `node --test src/main.test.js` — run a single test file. Add `--test-name-pattern ''` to filter by test name. - `npm run lint` — Prettier format check + ESLint. `npm run lint:format:fix` and From c49567d4f0464136820f30c8c2c6f96791334f2d Mon Sep 17 00:00:00 2001 From: Justin Stayton Date: Thu, 8 Oct 2026 06:10:45 -0400 Subject: [PATCH 2/2] Address CI review feedback Fixes VISION-4310. --- .github/workflows/ci.yml | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a9e1f3a..481a5b7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,6 +15,7 @@ concurrency: defaults: run: + # Explicit bash enables pipefail so tee cannot hide test failures. shell: bash jobs: @@ -25,7 +26,10 @@ jobs: strategy: fail-fast: false matrix: - node-version: ['22.x', '24.x', '26.x'] + node-version: ['22.x', '24.x'] + include: + - node-version: '26.x' + is-primary: true steps: - name: Check out repository uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 @@ -37,23 +41,23 @@ jobs: - name: Install npm dependencies run: npm ci - name: Run lint - if: matrix.node-version == '26.x' + if: matrix.is-primary run: npm run lint - name: Run typecheck - if: matrix.node-version == '26.x' + if: matrix.is-primary run: npm run typecheck - name: Run tests - if: matrix.node-version != '26.x' + if: ${{ !matrix.is-primary }} run: npm test - name: Run tests with coverage - if: matrix.node-version == '26.x' + if: matrix.is-primary run: npm run test:coverage | tee "$RUNNER_TEMP/tests.txt" # Reported in its own step so the summary is still written when the suite # fails, which is when the test results are most worth reading. Node # prints both its summary and the coverage report even on failure. - name: Report test results & coverage if: - ${{ !cancelled() && matrix.node-version == '26.x' && + ${{ !cancelled() && matrix.is-primary && hashFiles('coverage/lcov.info') != '' }} run: | { @@ -71,9 +75,9 @@ jobs: } >> "$GITHUB_STEP_SUMMARY" - name: Upload coverage report if: - ${{ !cancelled() && matrix.node-version == '26.x' && + ${{ !cancelled() && matrix.is-primary && hashFiles('coverage/lcov.info') != '' }} - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 with: name: coverage-${{ github.run_attempt }} path: coverage/