Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 66 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
name: CI

on:
push:
branches: [main]
pull_request:
branches: [main]

jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
# Pin the floor (20 matches `engines` in package.json) so a regression
# that only appears on the oldest supported Node still fails CI.
node-version: [20, 22, 24]
steps:
- uses: actions/checkout@v7

- uses: pnpm/action-setup@v6

- uses: actions/setup-node@v6
with:
node-version: ${{ matrix.node-version }}
cache: pnpm

- run: pnpm install --frozen-lockfile

- run: pnpm run test:coverage

- run: pnpm run build

# verify:dist reads the built dist/ and is the gate that caught the
# internal-symbol leak (ADR-007) while src sat at 100% coverage. Runs
# after build, on every Node so a Node-specific build regression fails here.
- run: pnpm run verify:dist

- uses: actions/upload-artifact@v7
if: always()
with:
name: coverage-node-${{ matrix.node-version }}
path: coverage/

static:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7

- uses: pnpm/action-setup@v6

# Static checks (format, lint, type) are Node-independent — run once on a
# modern Node rather than across the runtime matrix above.
- uses: actions/setup-node@v6
with:
node-version: 24
cache: pnpm

- run: pnpm install --frozen-lockfile

- run: pnpm run format:check

- run: pnpm run lint

- run: pnpm run typecheck

- run: pnpm run typecheck:test-types
37 changes: 37 additions & 0 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
name: Publish

on:
push:
tags: ['v*']

jobs:
publish:
runs-on: ubuntu-latest
permissions:
contents: write
id-token: write
steps:
- uses: actions/checkout@v7

- uses: pnpm/action-setup@v6

- uses: actions/setup-node@v6
with:
node-version: 24
cache: pnpm
registry-url: https://registry.npmjs.org

- run: pnpm install --frozen-lockfile

- run: pnpm run test:coverage

- run: pnpm run build

- run: pnpm run verify:dist

- run: npm publish --provenance --access public

- name: Create GitHub Release
env:
GH_TOKEN: ${{ github.token }}
run: gh release create "${GITHUB_REF_NAME}" --verify-tag --generate-notes --title "${GITHUB_REF_NAME}"
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,8 @@
"javascript"
],
"license": "MIT",
"packageManager": "pnpm@10.33.4",
"engines": {
"node": ">=18"
"node": ">=20"
}
}
30 changes: 15 additions & 15 deletions test-types/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
{
"compilerOptions": {
"target": "ESNext",
"module": "ESNext",
"lib": ["ESNext"],
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true,
"moduleResolution": "node",
"allowSyntheticDefaultImports": true,
"noEmit": true
},
"include": ["./**/*.ts"],
"exclude": ["node_modules"]
"compilerOptions": {
"target": "ESNext",
"module": "ESNext",
"lib": ["ESNext"],
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true,
"moduleResolution": "node",
"allowSyntheticDefaultImports": true,
"noEmit": true
},
"include": ["./**/*.ts"],
"exclude": ["node_modules"]
}