From 13c0108801892bab929626981d5b77a6ef63129c Mon Sep 17 00:00:00 2001 From: Thijs Koerselman Date: Tue, 17 Feb 2026 10:18:54 +0100 Subject: [PATCH 1/5] Add publishing workflow with OIDC provenance Add a manual dispatch workflow for publishing to npm using OIDC-based provenance. The workflow runs checks first, builds the package, bumps the version, publishes with provenance, and creates a GitHub release. Also bump Node.js to 24 in both checks and publish workflows. --- .github/workflows/checks.yml | 2 +- .github/workflows/publish.yml | 125 ++++++++++++++++++++++++++++++++++ 2 files changed, 126 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/publish.yml diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml index 9af7019..b39edf0 100644 --- a/.github/workflows/checks.yml +++ b/.github/workflows/checks.yml @@ -30,7 +30,7 @@ jobs: - name: Setup Node.js uses: actions/setup-node@v4 with: - node-version: 22 + node-version: 24 - name: Enable corepack run: corepack enable pnpm diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 0000000..43ee0e1 --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,125 @@ +name: Publish + +on: + workflow_dispatch: + inputs: + bump: + description: "Version bump type" + required: true + type: choice + options: + - patch + - minor + - major + - prepatch + - preminor + - premajor + - prerelease + preid: + description: "Prerelease identifier (alpha, beta, rc). Only used with pre* bumps." + required: false + type: string + dry_run: + description: "Dry run — skip publish, push, and release" + required: false + type: boolean + default: false + +concurrency: + group: publish + cancel-in-progress: false + +jobs: + checks: + if: github.ref == 'refs/heads/main' + uses: ./.github/workflows/checks.yml + + publish: + needs: checks + runs-on: ubuntu-latest + permissions: + contents: write + id-token: write + + steps: + - uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: 24 + registry-url: "https://registry.npmjs.org" + + - name: Enable corepack + run: corepack enable pnpm + + - name: Install dependencies + run: pnpm install --frozen-lockfile + + - name: Build + run: pnpm build + + - name: Configure git + run: | + git config user.name "github-actions[bot]" + git config user.email "41898282+github-actions[bot]@users.noreply.github.com" + + - name: Bump version + id: version + env: + BUMP: ${{ inputs.bump }} + PREID: ${{ inputs.preid }} + run: | + ARGS=("$BUMP") + if [[ "$BUMP" == pre* && -n "$PREID" ]]; then + ARGS+=(--preid "$PREID") + fi + + npm version "${ARGS[@]}" --git-tag-version true + + VERSION=$(node -p "require('./package.json').version") + TAG="v${VERSION}" + + echo "version=${VERSION}" >> $GITHUB_OUTPUT + echo "tag=${TAG}" >> $GITHUB_OUTPUT + + if [[ "$VERSION" == *-* ]]; then + echo "dist_tag=next" >> $GITHUB_OUTPUT + echo "prerelease=true" >> $GITHUB_OUTPUT + else + echo "dist_tag=latest" >> $GITHUB_OUTPUT + echo "prerelease=false" >> $GITHUB_OUTPUT + fi + + - name: Publish summary + run: | + echo "### Publish Summary" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "- **Version:** ${{ steps.version.outputs.version }}" >> $GITHUB_STEP_SUMMARY + echo "- **Tag:** ${{ steps.version.outputs.tag }}" >> $GITHUB_STEP_SUMMARY + echo "- **Dist tag:** ${{ steps.version.outputs.dist_tag }}" >> $GITHUB_STEP_SUMMARY + echo "- **Prerelease:** ${{ steps.version.outputs.prerelease }}" >> $GITHUB_STEP_SUMMARY + echo "- **Dry run:** ${{ inputs.dry_run }}" >> $GITHUB_STEP_SUMMARY + + - name: Publish to npm + if: ${{ inputs.dry_run == false }} + run: | + npm publish --provenance --tag ${{ steps.version.outputs.dist_tag }} + + - name: Push commit and tag + if: ${{ inputs.dry_run == false }} + run: git push origin HEAD --follow-tags + + - name: Create GitHub Release + if: ${{ inputs.dry_run == false }} + run: | + PRERELEASE_FLAG="" + if [[ "${{ steps.version.outputs.prerelease }}" == "true" ]]; then + PRERELEASE_FLAG="--prerelease" + fi + + gh release create "${{ steps.version.outputs.tag }}" \ + --generate-notes \ + $PRERELEASE_FLAG + env: + GH_TOKEN: ${{ github.token }} From f5b9b1e1a55e0987fc2895b093c835437adfad7d Mon Sep 17 00:00:00 2001 From: Thijs Koerselman Date: Tue, 17 Feb 2026 10:20:05 +0100 Subject: [PATCH 2/5] Format publish workflow with Prettier --- .github/workflows/publish.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 43ee0e1..d9cc70a 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -16,7 +16,8 @@ on: - premajor - prerelease preid: - description: "Prerelease identifier (alpha, beta, rc). Only used with pre* bumps." + description: + "Prerelease identifier (alpha, beta, rc). Only used with pre* bumps." required: false type: string dry_run: From 3bbbc4cebddc4e6d00a956f992beb3c4bd69c01f Mon Sep 17 00:00:00 2001 From: Thijs Koerselman Date: Tue, 17 Feb 2026 10:24:45 +0100 Subject: [PATCH 3/5] Add comment explaining publish-before-push ordering --- .github/workflows/publish.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index d9cc70a..2a76f29 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -102,6 +102,9 @@ jobs: echo "- **Prerelease:** ${{ steps.version.outputs.prerelease }}" >> $GITHUB_STEP_SUMMARY echo "- **Dry run:** ${{ inputs.dry_run }}" >> $GITHUB_STEP_SUMMARY + # Publish before push: npm publish is not retryable (same version + # can't be published twice), while git push is idempotent. If push + # fails after a successful publish, it can simply be retried manually. - name: Publish to npm if: ${{ inputs.dry_run == false }} run: | From 4c389482cfdf8665d91376dfd1cbdd48f1b8ce79 Mon Sep 17 00:00:00 2001 From: Thijs Koerselman Date: Tue, 17 Feb 2026 10:25:29 +0100 Subject: [PATCH 4/5] Add explicit main branch condition to publish job --- .github/workflows/publish.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 2a76f29..6f155af 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -36,6 +36,7 @@ jobs: uses: ./.github/workflows/checks.yml publish: + if: github.ref == 'refs/heads/main' needs: checks runs-on: ubuntu-latest permissions: From d226cc32b076130cd498e9bff58c630ae85b01a8 Mon Sep 17 00:00:00 2001 From: Thijs Koerselman Date: Tue, 17 Feb 2026 12:48:21 +0100 Subject: [PATCH 5/5] Add comment clarifying OIDC-based authentication --- .github/workflows/publish.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 6f155af..d8926a7 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -39,6 +39,8 @@ jobs: if: github.ref == 'refs/heads/main' needs: checks runs-on: ubuntu-latest + # Authentication is handled via OIDC trusted publishing (id-token), + # so no NPM_TOKEN secret is needed. permissions: contents: write id-token: write