👷 Type-check the TS floor in CI

Add a `compat` job that type-checks the whole suite and a consumer fixture
against the minimum supported TypeScript (5.9), reusing the `dist/` artifact
`build` produced and gating `publish`. The compiler is resolved by npx, so it
never enters `devDependencies` or the local `check`/`verify` loop.

The fixture imports the package by name, resolving the emitted declarations
through the `exports` map; `expectTypeOf` / `.not.toBeAny()` make it reject an
`any`-typed declaration, which a bare compile would accept.

Correct the README consumer floor from >= 5.0 to >= 5.9 (set by `type-fest`)
and drop the `node10` resolution claim, which the exports-only entry never
satisfied.
This commit is contained in:
tmu committed 2026-09-29 20:51:41 +00:00
1 parent 45df45df4b
commit 75807c4bd8
10 files changed
+218 -8

No files matched your search

+32 -1
View File
@@ -119,6 +119,35 @@ jobs:
name: dist
path: dist/
# Consumer typecheck against the minimum supported TypeScript (README
# § Requirements), run over `dist/`'s emitted declarations and the whole
# suite. Deliberately a separate job, not a step in `build`: the compiler is
# a different major picked by `npx`, and it must never enter
# `devDependencies`, the local `check`/`verify` tiers, or the lockfile. See
# development/ci.md § TypeScript compatibility.
compat:
needs: build
runs-on: ubuntu-latest
# Same baked image as `build` — without it this job re-downloads Node
# per run (see docker/Dockerfile).
container:
image: gitea.e1nsnull.de/tmu/act-ci:26.8.2
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version-file: .node-version
cache: "npm"
- run: npm ci
# Reuse the exact `dist/` that `check`, `test:ci` and `publint` were
# run against, so the compat gate judges the shipped artifact and
# pays no rebuild.
- uses: actions/download-artifact@v4
with:
name: dist
path: dist/
- run: npm run test:compat
# Advisory scans (dead code, dependency freshness). Non-blocking: surfaced in
# the Actions tab for visibility, but must never gate a merge — so
# continue-on-error and intentionally NOT in `publish`'s `needs`.
@@ -142,7 +171,9 @@ jobs:
publish:
if: startsWith(gitea.ref, 'refs/tags/')
needs: build
# `compat` gates the release: an artifact that is not consumable at the
# claimed TypeScript floor must never ship.
needs: [build, compat]
runs-on: ubuntu-latest
# Same baked image as `build` — setup-node still owns the registry-url
# `.npmrc` rewrite here; only the Node download is skipped.