From 9564a6e5dca46852271bd693c7f3d18b35ee6852 Mon Sep 17 00:00:00 2001 From: Sean C Davis Date: Fri, 4 Sep 2026 13:45:50 -0400 Subject: [PATCH 1/3] ci: run the unit tests on pull requests The repo has 53 test files and 1139 tests wired to `npm test`, but nothing ran them outside of a release. Adds a test workflow on pull_request and on push to main, mirroring the install steps the publish job already uses. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_015szZZVWisbftpCqioACuB5 --- .github/workflows/test.yml | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 .github/workflows/test.yml diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..ab0f77e --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,30 @@ +--- +name: test +on: + pull_request: + push: + branches: + - main + +# A new push supersedes the run in flight for the same ref. +concurrency: + group: test-${{ github.ref }} + cancel-in-progress: true + +jobs: + unit: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v6 + + - uses: actions/setup-node@v6 + with: + node-version: "24" + cache: npm + + - name: Install dependencies + run: npm ci --no-audit + + # vitest runs against src/, so no build step is needed here. + - name: Run unit tests + run: npm test From 9ea734ce6e06f6335aeb6fc32b2cdb27f8961e38 Mon Sep 17 00:00:00 2001 From: Sean C Davis Date: Fri, 4 Sep 2026 13:47:44 -0400 Subject: [PATCH 2/3] ci: build the report UI before running the tests test/unit/reports/html.test.ts reads dist/report-ui/index.html, which is gitignored, so 29 tests fail on a clean checkout. Local runs passed only because dist/ was left over from an earlier build. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_015szZZVWisbftpCqioACuB5 --- .github/workflows/test.yml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index ab0f77e..bd4c122 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -25,6 +25,11 @@ jobs: - name: Install dependencies run: npm ci --no-audit - # vitest runs against src/, so no build step is needed here. + # test/unit/reports/html.test.ts reads dist/report-ui/index.html, so the + # report UI has to be built before the suite runs. The rest of the tests + # run against src/ directly, so a full `npm run build` isn't needed. + - name: Build report UI + run: npm run build:report-ui + - name: Run unit tests run: npm test From 411cf825fb6c069e052403bb835a57e6f7c39821 Mon Sep 17 00:00:00 2001 From: Sean C Davis Date: Fri, 4 Sep 2026 13:55:49 -0400 Subject: [PATCH 3/3] ci: harden the test workflow's token exposure The job runs PR-controlled code through npm lifecycle scripts, the report UI build, and the tests. Pin GITHUB_TOKEN to contents:read rather than inheriting org defaults, and drop the persisted checkout credentials since no step needs authenticated git. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_015szZZVWisbftpCqioACuB5 --- .github/workflows/test.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index bd4c122..8bec29a 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -11,11 +11,19 @@ concurrency: group: test-${{ github.ref }} cancel-in-progress: true +# The job only reads the repo. Anything unlisted here is unavailable to it. +permissions: + contents: read + jobs: unit: runs-on: ubuntu-latest steps: + # No step needs authenticated git, so don't leave the token in the + # checkout for npm lifecycle scripts and the test suite to reach. - uses: actions/checkout@v6 + with: + persist-credentials: false - uses: actions/setup-node@v6 with: