From f489f0e8c8897251eea71fb81a9d65045f39c27c Mon Sep 17 00:00:00 2001 From: Mark Probst Date: Mon, 20 Jul 2026 09:15:02 -0400 Subject: [PATCH 1/3] Add CI and npm-publish GitHub Actions workflows CI runs typecheck, build, and tests on pull requests and on pushes to main. Publish runs when a GitHub release is published: it sets the package version from the release tag (stripping a leading v), runs the checks, and publishes to npm with provenance. Prereleases go to the "next" dist-tag so they never become npm's "latest". Actions are pinned to commit SHAs. Co-Authored-By: Claude Fable 5 --- .github/workflows/ci.yml | 26 ++++++++++++++++++++++ .github/workflows/publish.yml | 41 +++++++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+) create mode 100644 .github/workflows/ci.yml create mode 100644 .github/workflows/publish.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..0d86bcb --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,26 @@ +name: CI + +on: + push: + branches: [main] + pull_request: + +jobs: + check: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + + # tsdown requires ^22.18.0 || >=24.11.0 + - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 + with: + node-version: 24 + cache: npm + + - run: npm ci + + - run: npm run typecheck + + - run: npm run build + + - run: npm test diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 0000000..4633c82 --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,41 @@ +name: Publish + +on: + release: + types: [published] + +jobs: + publish: + runs-on: ubuntu-latest + permissions: + contents: read + # Required for npm provenance + id-token: write + steps: + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + + # tsdown requires ^22.18.0 || >=24.11.0 + - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 + with: + node-version: 24 + cache: npm + registry-url: https://registry.npmjs.org + + - run: npm ci + + - run: npm run typecheck + + - run: npm test + + # Take the version from the release tag (strip a leading "v"). + - name: Set version from release tag + run: npm version --no-git-tag-version "${TAG#v}" + env: + TAG: ${{ github.event.release.tag_name }} + + # prepublishOnly runs the build. GitHub prereleases go to the + # "next" dist-tag so they never become npm's "latest". + - run: npm publish --provenance --tag "${DIST_TAG}" + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} + DIST_TAG: ${{ github.event.release.prerelease && 'next' || 'latest' }} From ef20ebdb491944edd8526f788ffaa89a9643fb9a Mon Sep 17 00:00:00 2001 From: Mark Probst Date: Mon, 20 Jul 2026 09:19:58 -0400 Subject: [PATCH 2/3] Use npm trusted publishing instead of a token secret Co-Authored-By: Claude Fable 5 --- .github/workflows/publish.yml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 4633c82..11a5b85 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -33,9 +33,10 @@ jobs: env: TAG: ${{ github.event.release.tag_name }} - # prepublishOnly runs the build. GitHub prereleases go to the - # "next" dist-tag so they never become npm's "latest". + # Auth is via npm trusted publishing (OIDC, requires the + # id-token permission above) — no token secret. prepublishOnly + # runs the build. GitHub prereleases go to the "next" dist-tag + # so they never become npm's "latest". - run: npm publish --provenance --tag "${DIST_TAG}" env: - NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} DIST_TAG: ${{ github.event.release.prerelease && 'next' || 'latest' }} From ce0f101bdf9b2fafa250ddc6e6d4cd2bb72871cf Mon Sep 17 00:00:00 2001 From: Mark Probst Date: Mon, 20 Jul 2026 09:24:19 -0400 Subject: [PATCH 3/3] Allow the release tag to match package.json's version npm version errors on a no-op change, which would fail the very first release: package.json is already at 0.4.0. Co-Authored-By: Claude Fable 5 --- .github/workflows/publish.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 11a5b85..e4dced1 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -28,8 +28,10 @@ jobs: - run: npm test # Take the version from the release tag (strip a leading "v"). + # --allow-same-version: npm errors on a no-op version change, + # which would fail releases whose tag matches package.json. - name: Set version from release tag - run: npm version --no-git-tag-version "${TAG#v}" + run: npm version --no-git-tag-version --allow-same-version "${TAG#v}" env: TAG: ${{ github.event.release.tag_name }}