Repository navigation
chore(release): publish to npm with trusted publishing - #2741
Conversation
Replace the three release-production workflows and release.json with one release.yml that runs on release:published, so the npm trusted publisher can be keyed on the filename. Drop NPM_TOKEN in favour of id-token: write (OIDC), run on Node 24 with npm@latest (trusted publishing needs npm >= 11.5.1), install with a frozen lockfile and check out the release tag without persisted credentials. Each package publishes in dependency order and is skipped when its version is already on npm, so one release publishes only what was bumped. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
✅ Snyk checks have passed. No issues have been found so far.
💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse. |
🔒 Security Scan Results
⏱️ SLA Breach Summary
ℹ️ Vulnerabilities Without Available Fixes (Informational Only)The following vulnerabilities were detected but do not have fixes available (no upgrade or patch). These are excluded from failure thresholds:
Consider reviewing these vulnerabilities when fixes become available. |
cli-config and cli-auth do not depend on each other, so pnpm --sort was free to publish auth before config. List the five packages explicitly in the order the old release workflows used: utilities, command, config, auth, then core. A failed publish still stops the step before the next package. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
🔒 Security Scan Results
⏱️ SLA Breach Summary
ℹ️ Vulnerabilities Without Available Fixes (Informational Only)The following vulnerabilities were detected but do not have fixes available (no upgrade or patch). These are excluded from failure thresholds:
Consider reviewing these vulnerabilities when fixes become available. |
Give each of the five packages its own publish step, as the old release workflows did, so a failed publish names the package in the Actions run and stops the job before the next one. The order is unchanged: utilities, command, config, auth, core. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
🔒 Security Scan Results
⏱️ SLA Breach Summary
ℹ️ Vulnerabilities Without Available Fixes (Informational Only)The following vulnerabilities were detected but do not have fixes available (no upgrade or patch). These are excluded from failure thresholds:
Consider reviewing these vulnerabilities when fixes become available. |
🔒 Security Scan Results
⏱️ SLA Breach Summary
ℹ️ Vulnerabilities Without Available Fixes (Informational Only)The following vulnerabilities were detected but do not have fixes available (no upgrade or patch). These are excluded from failure thresholds:
Consider reviewing these vulnerabilities when fixes become available. |
Lock file regenerated (fixed 2 on its own: follow-redirects 1.16.0 -> 1.16.2). Direct upgrades: none Overrides: none added (the fast-uri 4.2.3, uuid 14.0.3 and js-yaml 5.5.0 pins are already on this branch) Vuln count vs main: snyk 41 -> 11, npm audit 7 -> 3. Build verified passing. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
🔒 Security Scan Results
⏱️ SLA Breach Summary
ℹ️ Vulnerabilities Without Available Fixes (Informational Only)The following vulnerabilities were detected but do not have fixes available (no upgrade or patch). These are excluded from failure thresholds:
Consider reviewing these vulnerabilities when fixes become available. |
Problem
The three
release-production-*.ymlworkflows publish the 5 cli packages to npm with a long-livedNPM_TOKENon every push tomain.The SE1 publishing policy requires OIDC trusted publishing instead: no token, one
release.ymlthat runs when a release is published, Node 24.Every run since August also ends red: the post-publish
gh release createstep fails with HTTP 403.Fix
The three workflows and
.github/config/release.jsonare replaced by onerelease.yml.main, manual runrelease: publishedrelease-production-pipeline.ymlcalling…-platform-plugins.ymland…-core.ymlrelease.yml(npm checks the calling workflow's filename)NPM_TOKENid-token: write, no tokenJS-DevTools/npm-publish@v3steps: utilities, command, config, auth, then corenpm publish --access publicunless that version is already on npmclean:all, thenpnpm install --no-frozen-lockfilepnpm install --frozen-lockfilepersist-credentials: false@v4@v7, setup-node@v7, pnpm/action-setup pinned to its v6.1.0 commitjson-to-variables+release.json(unused), corepack steps,gh release create(403)GITGUARDIAN_API_KEYon the publish step.talismanrcrelease.yml: Talisman flags the pinned action SHA and thesecrets.reference (false positives)Deviations from the policy's sample workflow, all because this is a pnpm monorepo with 5 packages:
pnpm/action-setupstep: the repo uses pnpm.cache: 'pnpm'instead of'npm': there is nopackage-lock.json.pnpm install --frozen-lockfileinstead ofnpm ci: the same lockfile-strict install, for pnpm.pnpm -r --sort run build: when a release publishes only core, the skipped packages'prepacknever runs, and core's build needs theirlib/.GITGUARDIAN_API_KEY: the GitGuardian scan on publish.@v4(v4 runs on Node 20, which is end-of-life); the third-partypnpm/action-setupis pinned to a commit SHA, as SRE recommended.Verification
Node 22 and Node 24: frozen-lockfile install, build and unit tests pass (362 passing). The publish steps, run with
npm publishstubbed, go in the old order, skip the 5 versions already on npm, pick up a bumped one, and a failed step stops the job.Snyk
This PR also clears the repo's Snyk dependency findings that have a fix. Numbers are against
main(b639944).mainfast-uri4.2.1 → 4.2.3 through thepnpm-workspace.yamloverride pin: 4 Snyk findings.follow-redirects1.16.0 → 1.16.2 by regeneratingpnpm-lock.yaml: 2 Snyk findings. Every other change in the lock stays inside its current range. Nopackage.jsonchanged.@contentstack/cli-*ranges themselves.Still open:
csv-parse4.16.3 (viatty-table→csv5; the fix is 7.x, a major),picomatch4.0.7 andyarn1.22.22 (Snyk lists no fix), and the Artistic-2.0 licence onnpm(via@oclif/plugin-plugins). The remaining pnpm audit findings are dev-only:minimatch9.0.3 (viaeslint-config-oclif) andserialize-javascript6.0.2 (viamocha, the fix is a major).