Skip to content
Open
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
26 changes: 26 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
version: 2

updates:
# Action majors go stale silently — nothing fails when actions/checkout@v5 is
# two majors behind, it just quietly runs on an older runner image.
- package-ecosystem: github-actions
directory: /
schedule:
interval: monthly
commit-message:
prefix: "ci"

- package-ecosystem: npm
directories:
- /
- /example
schedule:
interval: monthly
commit-message:
prefix: "chore"
# Everything here is a devDependency; the published package has no runtime
# dependencies. One grouped PR a month is enough.
groups:
dev-dependencies:
patterns:
- "*"
62 changes: 62 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
name: CI

# Until this existed, nothing was verified before a merge: the checks lived only
# in the git hooks (skippable with --no-verify) and in the release workflow,
# which runs when the version has already been tagged.
on:
pull_request:
push:
branches:
- main

# Pushing again to a branch makes the run for the previous push pointless.
concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: true

env:
# The git hooks exist for developer machines; every check they run is a step
# below. Without this, `pnpm install` would set husky up on the runner.
HUSKY: 0

jobs:
check:
runs-on: ubuntu-latest
permissions:
contents: read

strategy:
fail-fast: false
matrix:
# engines allows Node >= 18, but the toolchain itself does not run
# there: tsdown requires ^22.18.0 || >=24.11.0 and jsdom requires
# ^22.22.2 || ^24.15.0 || >=26.0.0. The published bundle is browser
# code with no Node API in it, so what 18 has to support is importing
# it, which this suite would not exercise anyway.
node: [22, 24]

name: node ${{ matrix.node }}

steps:
- uses: actions/checkout@v5

- uses: pnpm/action-setup@v4

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

- run: pnpm install --frozen-lockfile

- run: pnpm run check-types

- run: pnpm run test:coverage

# Also validates the publishable package: the build runs publint and
# are-the-types-wrong.
- run: pnpm run build

# The example consumes the built package the way a published consumer
# does, so this catches exports and type-resolution breakage.
- run: pnpm --filter example run check-types
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ lerna-debug.log*
node_modules
dist
dist-ssr
coverage
*.local
*.tsbuildinfo

Expand Down
6 changes: 0 additions & 6 deletions .husky/pre-commit
Original file line number Diff line number Diff line change
@@ -1,8 +1,2 @@
pnpm run check-types
pnpm test

# Also validates the publishable package — the build runs publint and
# are-the-types-wrong.
pnpm run build

pnpm --filter example run check-types
9 changes: 9 additions & 0 deletions .husky/pre-push
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# The slower half of the checks, moved off pre-commit now that CI runs them on
# every pull request. Committing stays quick; nothing reaches the remote without
# the publishable package being validated.

# Validates the publishable package — the build runs publint and
# are-the-types-wrong.
pnpm run build

pnpm --filter example run check-types
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

_Nothing yet._

## 1.2.1 — 2026-08-16

Infrastructure only — the library itself is unchanged from 1.2.0.

### Build

- Publishing moved to GitHub Actions on tag push, authenticated with npm trusted
publishing over OIDC instead of a long-lived token, so releases now carry a
provenance statement. `npm version` no longer publishes from a developer
machine, and `prepublishOnly` refuses to.

## 1.2.0 — 2026-08-14

### Added
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
},
"scripts": {
"test": "vitest run",
"test:coverage": "vitest run --coverage",
"check-types": "tsc",
"build": "tsdown",
"release:patch": "npm version patch",
Expand Down
28 changes: 28 additions & 0 deletions vitest.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { defineConfig } from "vitest/config";

export default defineConfig({
test: {
coverage: {
// Only the published source counts. `all` keeps files that no test ever
// imports in the report, so a new module cannot arrive at 0% unnoticed.
all: true,
include: ["src/**/*.ts"],
exclude: ["src/**/*.test.ts"],
// The default `text` reporter prints an empty file table here (vitest
// 4.1.10) even though the data behind it is right — coverage-final.json
// and the HTML report both list the file. `text-summary` shows the
// numbers without the misleading blank table; `html` is where the
// per-line detail is, in coverage/index.html.
reporter: ["text-summary", "html"],
// The suite covers every line and branch today, so the threshold is the
// current state rather than an aspiration: new code arrives with tests,
// or CI goes red. Lower it deliberately if that ever stops being worth it.
thresholds: {
statements: 100,
branches: 100,
functions: 100,
lines: 100,
},
},
},
});
Loading