ci: migrate npm publishing to trusted OIDC

This commit is contained in:
DrSmoothl
2026-09-22 09:43:07 +08:00
parent fe245d84bf
commit 0591b160fb
5 changed files with 64 additions and 31 deletions
+30
View File
@@ -0,0 +1,30 @@
# npm Trusted Publishing
The npm publish workflows use GitHub Actions OIDC instead of a long-lived
`NPM_TOKEN`. Each package must have a matching Trusted Publisher entry on npm
before its first publish after this migration.
For each package (`@snowluma/sdk`, `@snowluma/ui`, and `@snowluma/mcp`), open
the package's npm settings and add a **GitHub Actions** trusted publisher with:
| Field | Value |
| --- | --- |
| Organization or user | `SnowLuma` |
| Repository | `SnowLuma` |
| Workflow filename | The exact filename below |
| Environment | `SnowLuma` |
| Package | Workflow filename |
| --- | --- |
| `@snowluma/sdk` | `sdk-npm-publish.yml` |
| `@snowluma/ui` | `ui-npm-publish.yml` |
| `@snowluma/mcp` | `mcp-npm-publish.yml` |
The workflow job keeps the `SnowLuma` GitHub Environment, so the environment
field must match exactly. The workflows grant `id-token: write`, use Node 24
(which provides a recent enough npm CLI), and publish with provenance. They do
not read `NPM_TOKEN`.
After all three entries are saved, rerun the failed workflow runs. Once a
successful publish is confirmed for every package, the obsolete `NPM_TOKEN`
environment secret can be removed from GitHub Actions settings.
+10 -10
View File
@@ -40,7 +40,10 @@ jobs:
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version-file: '.node-version'
# Trusted Publishing requires Node >=22.14 and npm >=11.5.1.
# Node 24 ships a supported npm CLI; the application runtime stays
# pinned separately by .node-version.
node-version: '24'
cache: 'pnpm'
registry-url: 'https://registry.npmjs.org'
@@ -77,21 +80,17 @@ jobs:
echo "already_published=false" >> "${GITHUB_OUTPUT}"
fi
- name: Validate npm token
- name: Show Trusted Publishing toolchain
if: steps.npm.outputs.already_published != 'true'
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
run: |
if [ -z "${NODE_AUTH_TOKEN}" ]; then
echo 'Missing NPM_TOKEN in the SnowLuma environment secrets.' >&2
exit 1
fi
node --version
npm --version
- name: Publish MCP to npm
if: steps.npm.outputs.already_published != 'true'
working-directory: packages/mcp
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
# Authentication is supplied by npm Trusted Publishing through the
# GitHub OIDC token (permissions.id-token: write above).
run: npm publish --access public --provenance
- name: Summary
@@ -106,4 +105,5 @@ jobs:
echo "| Version | \`${{ steps.npm.outputs.package_version }}\` |"
echo "| Already published | \`${{ steps.npm.outputs.already_published }}\` |"
echo "| Environment | \`SnowLuma\` |"
echo "| Authentication | npm Trusted Publishing (GitHub OIDC) |"
} >> "${GITHUB_STEP_SUMMARY}"
+10 -10
View File
@@ -37,7 +37,10 @@ jobs:
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version-file: '.node-version'
# Trusted Publishing requires Node >=22.14 and npm >=11.5.1.
# Node 24 ships a supported npm CLI; the application runtime stays
# pinned separately by .node-version.
node-version: '24'
cache: 'pnpm'
registry-url: 'https://registry.npmjs.org'
@@ -74,21 +77,17 @@ jobs:
echo "already_published=false" >> "${GITHUB_OUTPUT}"
fi
- name: Validate npm token
- name: Show Trusted Publishing toolchain
if: steps.npm.outputs.already_published != 'true'
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
run: |
if [ -z "${NODE_AUTH_TOKEN}" ]; then
echo 'Missing NPM_TOKEN in the SnowLuma environment secrets.' >&2
exit 1
fi
node --version
npm --version
- name: Publish SDK to npm
if: steps.npm.outputs.already_published != 'true'
working-directory: packages/sdk
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
# Authentication is supplied by npm Trusted Publishing through the
# GitHub OIDC token (permissions.id-token: write above).
run: npm publish --access public --provenance
- name: Summary
@@ -103,4 +102,5 @@ jobs:
echo "| Version | \`${{ steps.npm.outputs.package_version }}\` |"
echo "| Already published | \`${{ steps.npm.outputs.already_published }}\` |"
echo "| Environment | \`SnowLuma\` |"
echo "| Authentication | npm Trusted Publishing (GitHub OIDC) |"
} >> "${GITHUB_STEP_SUMMARY}"
+10 -10
View File
@@ -37,7 +37,10 @@ jobs:
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version-file: '.node-version'
# Trusted Publishing requires Node >=22.14 and npm >=11.5.1.
# Node 24 ships a supported npm CLI; the application runtime stays
# pinned separately by .node-version.
node-version: '24'
cache: 'pnpm'
registry-url: 'https://registry.npmjs.org'
@@ -71,21 +74,17 @@ jobs:
echo "already_published=false" >> "${GITHUB_OUTPUT}"
fi
- name: Validate npm token
- name: Show Trusted Publishing toolchain
if: steps.npm.outputs.already_published != 'true'
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
run: |
if [ -z "${NODE_AUTH_TOKEN}" ]; then
echo 'Missing NPM_TOKEN in the SnowLuma environment secrets.' >&2
exit 1
fi
node --version
npm --version
- name: Publish UI to npm
if: steps.npm.outputs.already_published != 'true'
working-directory: packages/ui
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
# Authentication is supplied by npm Trusted Publishing through the
# GitHub OIDC token (permissions.id-token: write above).
run: npm publish --access public --provenance
- name: Summary
@@ -100,4 +99,5 @@ jobs:
echo "| Version | \`${{ steps.npm.outputs.package_version }}\` |"
echo "| Already published | \`${{ steps.npm.outputs.already_published }}\` |"
echo "| Environment | \`SnowLuma\` |"
echo "| Authentication | npm Trusted Publishing (GitHub OIDC) |"
} >> "${GITHUB_STEP_SUMMARY}"
+4 -1
View File
@@ -34,7 +34,10 @@ Examples:
## Automated npm Publish
`.github/workflows/sdk-npm-publish.yml` publishes `@snowluma/sdk` when SDK-related files reach `main`, including the automated `dev` to `main` promotion flow. The publish job uses the GitHub Environment named `SnowLuma` and expects an environment secret named `NPM_TOKEN`.
`.github/workflows/sdk-npm-publish.yml` publishes `@snowluma/sdk` when SDK-related files reach `main`, including the automated `dev` to `main` promotion flow. The publish job uses npm Trusted Publishing with the GitHub Environment named `SnowLuma`; it authenticates through GitHub Actions OIDC and does not require an `NPM_TOKEN` secret.
The one-time npm settings for SDK, UI, and MCP are documented in
[`.github/npm-trusted-publishing.md`](../../.github/npm-trusted-publishing.md).
If the package version already exists on npm, the workflow skips publishing that run. Bump `packages/sdk/package.json` before merging SDK changes that should create a new npm release.