From 14e74dda608f2b50f87a842d1de6c3ad0997dc8c Mon Sep 17 00:00:00 2001 From: Evan Date: Fri, 16 Oct 2026 20:02:05 -0500 Subject: [PATCH] chore: prepare manual npm OIDC trusted publishing workflow --- .github/workflows/publish.yml | 89 ++++++++++++++++++++--------------- 1 file changed, 51 insertions(+), 38 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 6038c21..b1cfdf2 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -1,9 +1,14 @@ +# Manual release publishing using npm Trusted Publishing (OIDC). +# Never triggered by a GitHub release or tag push. name: Publish to npm on: - push: - tags: - - "v*.*.*" + workflow_dispatch: + inputs: + tag: + description: "Existing release tag (for example v0.3.0)" + required: true + type: string permissions: contents: read @@ -11,48 +16,56 @@ permissions: jobs: publish: - name: Publish package runs-on: ubuntu-latest - steps: - - name: Checkout repo + - name: Validate input and checkout tag + env: + RELEASE_TAG: ${{ inputs.tag }} + run: | + set -eu + if ! printf '%s' "$RELEASE_TAG" | grep -Eq '^v[0-9]+\.[0-9]+\.[0-9]+$'; then + echo "Expected a stable release tag such as v1.2.3" >&2 + exit 1 + fi + - name: Checkout release tag uses: actions/checkout@v4 + with: + ref: ${{ inputs.tag }} + persist-credentials: false - - name: Setup Node + - name: Set up Node for npm Trusted Publishing uses: actions/setup-node@v4 with: - node-version: 22 - cache: npm - registry-url: https://registry.npmjs.org/ - - - name: Install dependencies - run: npm ci - - - name: Compile detection rules from TOML - run: npm run build:rules - - - name: Typecheck - run: npm run typecheck + node-version: '24' + registry-url: https://registry.npmjs.org + package-manager-cache: false - - name: Lint - run: npm run lint + - name: Require current npm OIDC client + run: npm install --global 'npm@^11.5.1' - - name: Unit tests - run: npm run test:unit - - - name: Integration tests - run: npm run test:integration - - - name: Security regression tests - run: npm run test:security - - - name: Build - run: npm run build + - name: Verify version and tag + env: + RELEASE_TAG: ${{ inputs.tag }} + run: | + set -eu + actual="$(node -p "require('./package.json').version")" + test "$RELEASE_TAG" = "v$actual" || { + echo "Version mismatch: $RELEASE_TAG vs $actual" >&2 + exit 1 + } + echo "Verified release $RELEASE_TAG" - - name: Package validation - run: npm run verify:package + - name: Install dependencies + run: npm ci + - name: Build and validate + run: | + npm run build + npm run typecheck + npm run lint + npm run test:unit + npm run test:integration + npm run test:security + npm run verify:package - - name: Publish to npm - run: npm publish --provenance --access public - env: - NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} + - name: Publish using OIDC + run: npm publish --access public