From 807e7f55123ab7b7711e2f8b2e77986b2ed0ac93 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 1 Aug 2026 19:54:07 +0000 Subject: [PATCH 1/2] Initial plan From a0353445118ddff63d42966a436eb74a31e39c75 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 1 Aug 2026 19:56:24 +0000 Subject: [PATCH 2/2] Prefer OIDC trusted publishing for npm release job --- .github/workflows/npm-publish.yml | 8 +++--- docs/RELEASE.md | 4 +-- scripts/publish-npm.cjs | 46 +++++++++++++++++++++++-------- 3 files changed, 41 insertions(+), 17 deletions(-) diff --git a/.github/workflows/npm-publish.yml b/.github/workflows/npm-publish.yml index a0baeb2..097256c 100644 --- a/.github/workflows/npm-publish.yml +++ b/.github/workflows/npm-publish.yml @@ -1,6 +1,6 @@ # Publishes @mitii/v8 → @mitii/sdk → @mitii/host → @mitii/cli to npm. # Invoked from the Release workflow on v* tags, or manually via workflow_dispatch. -# Requires repository secret: NPM_TOKEN +# Prefers GitHub OIDC trusted publishing; NPM_TOKEN is optional fallback. name: npm publish on: @@ -21,12 +21,12 @@ jobs: node-version: 20 registry-url: https://registry.npmjs.org cache: pnpm - - name: Require NPM_TOKEN + - name: Require publish auth env: NPM_TOKEN: ${{ secrets.NPM_TOKEN }} run: | - if [ -z "$NPM_TOKEN" ]; then - echo "::error::NPM_TOKEN secret is missing. Add an npm automation token in repo Settings → Secrets → Actions." + if [ -z "${ACTIONS_ID_TOKEN_REQUEST_URL:-}" ] && [ -z "$NPM_TOKEN" ]; then + echo "::error::No publish auth configured. Enable npm trusted publishing for this repo (recommended) or set NPM_TOKEN." exit 1 fi - name: Install native build tools diff --git a/docs/RELEASE.md b/docs/RELEASE.md index 28d4376..9332b94 100644 --- a/docs/RELEASE.md +++ b/docs/RELEASE.md @@ -51,7 +51,7 @@ Add these under **Settings → Secrets and variables → Actions** (values are n | Secret | Required | Purpose | |---|---|---| -| `NPM_TOKEN` | Yes (npm job) | npm automation token with publish rights for `@mitii/*` | +| `NPM_TOKEN` | Optional fallback | npm automation token with publish rights for `@mitii/*` when trusted publishing is not configured | | `VSCE_PAT` | Yes (marketplace job) | Azure DevOps PAT with Marketplace publish scope for publisher `mitii` | | `OVSX_PAT` | Optional | Open VSX token; Open VSX publish is skipped when unset | @@ -66,7 +66,7 @@ Add these under **Settings → Secrets and variables → Actions** (values are n - Attach them to a GitHub Release - Publish all four targets to the VS Code Marketplace (`VSCE_PAT`) - Publish to Open VSX when `OVSX_PAT` is set - - Call **npm publish** for `@mitii/v8` → `@mitii/sdk` → `@mitii/host` → `@mitii/cli` (`NPM_TOKEN`) + - Call **npm publish** for `@mitii/v8` → `@mitii/sdk` → `@mitii/host` → `@mitii/cli` (GitHub OIDC trusted publishing, with `NPM_TOKEN` fallback) ### Local / manual diff --git a/scripts/publish-npm.cjs b/scripts/publish-npm.cjs index 967ca8b..0988be6 100644 --- a/scripts/publish-npm.cjs +++ b/scripts/publish-npm.cjs @@ -1,10 +1,16 @@ const { spawnSync } = require('node:child_process'); const packages = ['@mitii/v8', '@mitii/sdk', '@mitii/host', '@mitii/cli']; +const hasToken = Boolean(process.env.NODE_AUTH_TOKEN || process.env.NPM_TOKEN); +const hasGithubOidc = Boolean( + process.env.GITHUB_ACTIONS && + process.env.ACTIONS_ID_TOKEN_REQUEST_URL && + process.env.ACTIONS_ID_TOKEN_REQUEST_TOKEN, +); -if (!process.env.NODE_AUTH_TOKEN && !process.env.NPM_TOKEN) { +if (!hasGithubOidc && !hasToken) { console.error( - 'Missing npm auth token. Set NODE_AUTH_TOKEN (or NPM_TOKEN) before publishing.', + 'Missing npm auth. Configure GitHub OIDC trusted publishing or set NODE_AUTH_TOKEN (or NPM_TOKEN).', ); process.exit(1); } @@ -13,17 +19,35 @@ if (!process.env.NODE_AUTH_TOKEN && process.env.NPM_TOKEN) { process.env.NODE_AUTH_TOKEN = process.env.NPM_TOKEN; } +function publishWithPnpm(name, args, env = process.env) { + return spawnSync('pnpm', ['--filter', name, 'publish', ...args], { + stdio: 'inherit', + shell: process.platform === 'win32', + env, + }); +} + for (const name of packages) { console.log(`Publishing ${name}…`); - const result = spawnSync( - 'pnpm', - ['--filter', name, 'publish', '--access', 'public', '--no-git-checks'], - { - stdio: 'inherit', - shell: process.platform === 'win32', - env: process.env, - }, - ); + let result; + if (hasGithubOidc) { + const trustedEnv = { ...process.env }; + delete trustedEnv.NODE_AUTH_TOKEN; + delete trustedEnv.NPM_TOKEN; + result = publishWithPnpm( + name, + ['--access', 'public', '--no-git-checks', '--provenance'], + trustedEnv, + ); + if ((result.status ?? 1) !== 0 && hasToken) { + console.warn( + `Trusted publishing failed for ${name}; retrying with npm token authentication.`, + ); + result = publishWithPnpm(name, ['--access', 'public', '--no-git-checks']); + } + } else { + result = publishWithPnpm(name, ['--access', 'public', '--no-git-checks']); + } if ((result.status ?? 1) !== 0) { console.error(`Failed to publish ${name}`); process.exit(result.status ?? 1);