From 0feeebe29893271cfd36300c01d1d8639456eb7b Mon Sep 17 00:00:00 2001 From: Zachary Lyon Date: Mon, 3 Aug 2026 16:52:26 -0700 Subject: [PATCH] Publish via npm Trusted Publisher (OIDC) instead of NPM_TOKEN Match the org's CD_sdk_typescript.yml flow: tokenless OIDC publishing with a ref guard and manual-dispatch escape hatch. Node 24 in the publish job for npm >= 11.5 trusted-publishing support. Co-Authored-By: Claude Fable 5 --- .github/workflows/release.yml | 54 +++++++++++++++++++++++++++-------- 1 file changed, 42 insertions(+), 12 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index de79479..10534b5 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,39 +1,61 @@ --- name: Release -# Publish @tiny-fish/mcp to npm when a v* tag is pushed (e.g. v0.1.0). -# The tag itself is created by a human per docs/phases/release-runbook.md -# (npm version + git push --follow-tags). Requires the NPM_TOKEN secret -# (npm automation token for the @tiny-fish org) and id-token permission -# for --provenance attestation. +# Publish @tiny-fish/mcp to npm when a v* tag is pushed (e.g. v0.1.0); +# manual dispatch remains as an escape hatch (guarded to main or a v* tag). +# The tag is created by a human (npm version + git push --follow-tags). +# +# Auth: npm Trusted Publisher (OIDC) — no NODE_AUTH_TOKEN secret, matching +# the org's SDK publish flow. npmjs.com package settings must list +# tinyfish-io/tinyfish-mcp-server + release.yml as the trusted publisher. +# Provenance attestation is generated automatically under trusted publishing. on: push: tags: - "v*" + workflow_dispatch: + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: false jobs: publish: runs-on: ubuntu-latest permissions: contents: read - # Required for npm --provenance (Sigstore attestation via OIDC). + # Required for OIDC trusted publishing (and its provenance attestation). id-token: write steps: - name: Checkout code uses: actions/checkout@v4 + # A dispatch at any other ref must go red, not green-skip — an operator + # would think it published when nothing uploaded. + - name: Require main or v* tag ref + run: | + case "$GITHUB_REF" in + refs/heads/main|refs/tags/v*) ;; + *) + echo "ERROR: dispatch at main or a v* tag, not '$GITHUB_REF_NAME'" >&2 + exit 1 + ;; + esac - name: Setup Node.js uses: actions/setup-node@v4 with: - node-version: 22 + # Node 24 ships npm >= 11.5, required for OIDC trusted publishing + # (consumers still only need Node >= 22 per engines). + node-version: 24 cache: npm registry-url: https://registry.npmjs.org - name: Install dependencies run: npm ci - name: Assert tag matches package.json version # A mistyped tag (v0.2.0 on a 0.1.0 tree) must fail before publish. + if: startsWith(github.ref, 'refs/tags/v') run: | pkg_version="$(node -p "require('./package.json').version")" if [ "${GITHUB_REF_NAME}" != "v${pkg_version}" ]; then - echo "Tag ${GITHUB_REF_NAME} does not match package.json version ${pkg_version}" >&2 + echo "Tag ${GITHUB_REF_NAME} != package.json ${pkg_version}" >&2 exit 1 fi - name: Lint @@ -42,9 +64,17 @@ jobs: run: npm run type-check - name: Build run: npm run build + - name: Verify build output + run: | + if [ ! -x dist/index.js ]; then + echo "ERROR: dist/index.js missing or not executable" >&2 + exit 1 + fi - name: Unit tests run: npm test - - name: Publish to npm - run: npm publish --provenance --access public - env: - NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} + - name: Publish to npm (@latest) + run: | + VERSION="$(node -p "require('./package.json').version")" + echo "Publishing @tiny-fish/mcp@${VERSION} as @latest (public)..." + npm publish --access public + echo "Published @tiny-fish/mcp@${VERSION}"