From 89dfef36007f1420c58e23465bdfc6329d316ec5 Mon Sep 17 00:00:00 2001 From: Kurt Overmier Date: Sat, 18 Apr 2026 03:24:40 -0500 Subject: [PATCH 1/2] ci(release): publish to npm on tag push MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The existing Release workflow only creates a GitHub Release tag — it doesn't publish to npm. v0.11.0 has shipped on GitHub since 2026-04-16 but npm is still at 0.10.0 across all 11 workspace packages because no step invokes `pnpm publish`. Add a `publish-npm` job parallel to `publish-release`: - `pnpm -r publish --access public --no-git-checks --provenance` - version-sync guard (fails if any packages/*/package.json version doesn't match the tag) - `id-token: write` for npm provenance attestation - same triggers as publish-release (tag push + workflow_dispatch backfill) After merge, backfill v0.11.0 via: gh workflow run release.yml -f tag=v0.11.0 Requires `NPM_TOKEN` repository secret (granular automation token with publish permission on @stackbilt/*). Co-Authored-By: Claude Opus 4.7 (1M context) --- .github/workflows/release.yml | 47 +++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index a0ebb28..fd9604d 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -92,3 +92,50 @@ jobs: name: ${{ steps.tag.outputs.value }} body_path: release_notes.md generate_release_notes: true + + publish-npm: + if: startsWith(github.ref, 'refs/tags/v') || github.event_name == 'workflow_dispatch' + runs-on: ubuntu-latest + permissions: + contents: read + id-token: write + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + fetch-depth: 0 + ref: ${{ inputs.tag || github.ref }} + + - uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v4.4.0 + + - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 + with: + node-version: '20' + cache: 'pnpm' + registry-url: 'https://registry.npmjs.org' + + - name: Install dependencies + run: pnpm install --frozen-lockfile + + - name: Build + run: pnpm run build + + - name: Verify workspace versions match tag + shell: bash + run: | + TAG="${{ github.event.inputs.tag || github.ref_name }}" + EXPECTED="${TAG#v}" + FAIL=0 + for p in packages/*/package.json; do + V=$(node -p "require('./$p').version") + N=$(node -p "require('./$p').name") + if [[ "$V" != "$EXPECTED" ]]; then + echo "::error::$N version $V does not match tag $EXPECTED" + FAIL=1 + fi + done + if [[ $FAIL -ne 0 ]]; then exit 1; fi + + - name: Publish to npm + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} + run: pnpm -r publish --access public --no-git-checks --provenance From bd395ecb93a13dfc3609160bf81d096147835c5e Mon Sep 17 00:00:00 2001 From: Kurt Overmier Date: Sat, 18 Apr 2026 03:46:10 -0500 Subject: [PATCH 2/2] ci(release): describe version-sync guard invariant One-line comment documenting that the guard enforces unified workspace versioning. Pre-merge cleanup from CodeBeast review of #118. Co-Authored-By: Claude Opus 4.7 (1M context) --- .github/workflows/release.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index fd9604d..a1c20aa 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -119,6 +119,7 @@ jobs: - name: Build run: pnpm run build + # Enforces unified workspace versioning — every packages/*/package.json must match the tag. - name: Verify workspace versions match tag shell: bash run: |