Skip to content

Improve security with npm staged publishing#301

Open
stijnvanhulle wants to merge 14 commits into
mainfrom
claude/inspiring-brahmagupta-6WXVB
Open

Improve security with npm staged publishing#301
stijnvanhulle wants to merge 14 commits into
mainfrom
claude/inspiring-brahmagupta-6WXVB

Conversation

@stijnvanhulle
Copy link
Copy Markdown
Contributor

Summary

Adds proper support for npm staged publishing by leaning on pnpm stage publish (pnpm 11.3+).

Previously each package carried its own release:stage script and the root coordinated them through turbo. That's redundant once pnpm stages workspace packages recursively.

  • Root release:stage is now pnpm stage publish -r --no-git-check --access public.
  • New scripts/release-stage.mjs drives CI: it reads .changeset/pre.json, forwards the active pre-tag (e.g. beta, rc) via --tag, then calls changeset tag and signals staged=true to $GITHUB_OUTPUT.
  • Drops the release:stage script from every package and the matching turbo task — there's a single source of truth now.

Changesets itself doesn't yet expose changeset publish --stage (tracked in changesets#2025); this keeps the existing staged workflow mode but reroutes it through the simpler script.

Test plan

  • Run the Release workflow in staged mode against the beta branch and confirm packages land in npm's staging area with the beta tag.
  • Approve via pnpm stage approve (or npm stage approve) and confirm promoted versions appear on latest/beta as expected.

Generated by Claude Code

Replace the turbo-driven per-package release:stage scripts with a single
recursive pnpm stage publish at the workspace root. A small
scripts/release-stage.mjs reads .changeset/pre.json so staged releases
inherit the active pre-mode tag (e.g. beta, rc) automatically.

- root release:stage now runs 'pnpm stage publish -r --no-git-check --access public'
- new scripts/release-stage.mjs orchestrates stage publish + changeset tag for CI
- drop release:stage from all per-package package.json files
- drop the release:stage turbo task
@codesandbox
Copy link
Copy Markdown

codesandbox Bot commented Jun 1, 2026

Review or Edit in CodeSandbox

Open the branch in Web EditorVS CodeInsiders

Open Preview

@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented Jun 1, 2026

⚠️ No Changeset found

Latest commit: ca00d3f

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@dosubot dosubot Bot added the size:S This PR changes 10-29 lines, ignoring generated files. label Jun 1, 2026
claude added 2 commits June 1, 2026 18:33
The 'release' and 'release:canary' scripts in each packages/*/package.json
referenced files that no longer exist (.github/canary.sh, scripts/build.js)
and were not invoked from anywhere. Canary and stable publishes both run
from the workspace root via changesets, so these per-package entries are
dead. Remove them along with the orphaned turbo tasks.
The release-stage.mjs script already gates the GITHUB_OUTPUT write on the
env var being set, so the same entry works for both local invocations and
CI. Drop the duplicate.
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jun 1, 2026

e18e dependency analysis

No dependency warnings found.

claude added 2 commits June 1, 2026 18:35
The changesets/action would intercept staged mode whenever pending
changesets exist (opening a Version PR instead of staging). Split the
flow so:

- version/publish modes keep using changesets/action
- staged mode skips the action entirely and runs 'pnpm release:stage'
  directly against the already-versioned tree

Promote MODE to a job-level env, drop the resolve-command shim, and key
the canary/notify gates on the stage step's staged output.
@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new Bot commented Jun 1, 2026

More templates

@kubb/plugin-client

npm i https://pkg.pr.new/@kubb/plugin-client@301

@kubb/plugin-cypress

npm i https://pkg.pr.new/@kubb/plugin-cypress@301

@kubb/plugin-faker

npm i https://pkg.pr.new/@kubb/plugin-faker@301

@kubb/plugin-mcp

npm i https://pkg.pr.new/@kubb/plugin-mcp@301

@kubb/plugin-msw

npm i https://pkg.pr.new/@kubb/plugin-msw@301

@kubb/plugin-react-query

npm i https://pkg.pr.new/@kubb/plugin-react-query@301

@kubb/plugin-redoc

npm i https://pkg.pr.new/@kubb/plugin-redoc@301

@kubb/plugin-swr

npm i https://pkg.pr.new/@kubb/plugin-swr@301

@kubb/plugin-ts

npm i https://pkg.pr.new/@kubb/plugin-ts@301

@kubb/plugin-vue-query

npm i https://pkg.pr.new/@kubb/plugin-vue-query@301

@kubb/plugin-zod

npm i https://pkg.pr.new/@kubb/plugin-zod@301

commit: ca00d3f

claude added 4 commits June 1, 2026 18:45
Strip the mode selector out of the workflow. The only publish action is
'pnpm release:stage', wired in as the publish command on
changesets/action. The action handles the rest:

- pending changesets present (push or workflow_dispatch) -> opens the
  'Version Packages' PR
- no pending changesets -> runs the staged publish

workflow_dispatch stays available as a manual trigger (no inputs) so a
maintainer can kick off Version PR creation on demand. Canary, test, and
codecov behaviors are unchanged.
Stage is the only release path now, so the qualifier is noise. Rename
the npm script and update the workflow + comment to call 'pnpm release'.
Closes the two gaps in the stage flow:

- pnpm stage publish's output doesn't match the '🦋  New tag:' format
  changesets/action scans for, so no GitHub Releases were ever created.
  Capture pnpm's --json output, parse the staged packages, and emit the
  marker per package so the action picks them up and creates a Release.
- 'changeset tag' produces local annotated tags, but nothing pushed them.
  Push the tags to origin after they're created so the GitHub Release
  has a remote tag to anchor to.

Discord notify already keys off steps.changesets.outputs.staged, which
the script sets, so it stays green.
@dosubot dosubot Bot added size:M This PR changes 30-99 lines, ignoring generated files. and removed size:S This PR changes 10-29 lines, ignoring generated files. labels Jun 1, 2026
claude added 4 commits June 1, 2026 19:05
If pnpm stage publish skips every package (because their current versions
are already on npm — typical for a feature merge that didn't bump
anything), we shouldn't signal staged=true. That lets the canary step
fire as intended on ordinary main pushes.
Drops the 'release' npm script alias. The workflow now calls
'node scripts/release.mjs' as the publish command on changesets/action.
Every push to main without a stage now publishes each workspace package
at 0.0.0-YYYYMMDDTHHMMSSZ under the canary dist-tag. The 0.0.0 base
sorts below any real release in semver, so canaries can't shadow stable
or pre-release versions on the latest tag.

Also drops the per-package date call — one timestamp is shared by all
packages in a given push so the canary set is internally consistent.
@stijnvanhulle stijnvanhulle changed the title ci: simplify staged publish via pnpm stage publish -r Improve security with npm staged publishing Jun 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:M This PR changes 30-99 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants