Configure CLI build pipeline for npm publishing#2697
Configure CLI build pipeline for npm publishing#2697ivan-ottinger wants to merge 11 commits intotrunkfrom
Conversation
There was a problem hiding this comment.
Pull request overview
This PR prepares the Studio CLI workspace package for publishing to npm under the new scoped name @automattic/studio-cli, including a dedicated npm-oriented build (externalized deps + shebang) and an npm-consumer postinstall pruning step.
Changes:
- Renames the CLI workspace/package to
@automattic/studio-cliand updates workspace script references. - Adds a dedicated
vite.config.npm.tsbuild that externalizes runtime dependencies and prepends a Node shebang tomain.js. - Adds an npm postinstall script to apply patches and prune large/unneeded binaries after install.
Reviewed changes
Copilot reviewed 5 out of 6 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| package.json | Updates root scripts to reference the new scoped CLI workspace and adds cli:build:npm. |
| package-lock.json | Reflects the CLI rename/versioning and dependency reshaping needed for npm publishing. |
| apps/studio/package.json | Updates Studio app scripts to call the renamed CLI workspace. |
| apps/cli/vite.config.npm.ts | Introduces npm-specific Vite build config (externalization + shebang injection + locales copy). |
| apps/cli/scripts/postinstall-npm.mjs | Adds npm-consumer postinstall actions (patches + binary pruning). |
| apps/cli/package.json | Updates CLI package metadata for npm publishing (name/version/bin/files/engines/scripts). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
fredrikekelund
left a comment
There was a problem hiding this comment.
Thanks for tackling this! The main questions I see here are:
- We need to think about how to handle
@studio/commonwhen publishing to npm. I don't think the current approach of just including those dependencies inapps/cli/package.jsonis reliable enough. - We should reduce the postinstall script as much as possible. In a follow-up PR, we should consider even removing
patch-packagealtogether.
| // Apply patches via patch-package | ||
| try { | ||
| execSync( 'npx --no-install patch-package --patch-dir ./patches', { | ||
| cwd: packageDir, | ||
| stdio: 'inherit', | ||
| } ); | ||
| } catch { | ||
| console.log( 'patch-package failed — patches may not apply cleanly' ); | ||
| } |
There was a problem hiding this comment.
Removing patch-package isn't trivial… The pm2-axon and pm2 patches will soon be redundant. We might be able to manage without the ps-man patch. The @wp-playground/wordpress patch could potentially be merged upstream in some way (gated by some config flag).
There was a problem hiding this comment.
Is there anything against keeping the patch-package?
Even if we clear current ones, there is a chance we will need hotfix something in the future, so it seems reasonable to have that way available for both UI and CLI.
There was a problem hiding this comment.
I expanded a little bit on the "why" in #2697 (comment)
Basically, the ideal end state to me is that we don't have a postinstall script when people install this package. pnpm disables the postinstall script by default and touts this as a security feature (which it is). Yarn mentions this in their docs:
Postinstall scripts should be avoided at all cost, as they make installs slower and riskier. Many users will refuse to install dependencies that have postinstall scripts. Additionally, since the output isn't shown out of the box, using them to print a message to the user will not work as you expect.
I don't know that the npm CLI has taken a stance on this, but given the multiple high-profile security incidents in the npm ecosystem in recent years, it's not unreasonable to expect them to address this.
For us, patch-package is the most difficult thing to remove. It's not feasible to tackle that in this PR, but the end goal of removing the postinstall script from the CLI package is definitely something we should consider.
531f4cb to
abf57d5
Compare
📊 Performance Test ResultsComparing b8819dc vs trunk site-editor
site-startup
Results are median values from multiple test runs. Legend: 🟢 Improvement (faster) | 🔴 Regression (slower) | ⚪ No change (<50ms diff) |
I have created related issue: STU-1375. |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 7 out of 8 changed files in this pull request and generated 3 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 7 out of 8 changed files in this pull request and generated 3 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
Add a separate Vite config (vite.config.npm.ts) that externalizes all runtime dependencies and adds a Node.js shebang, producing a standalone CLI package publishable to npm as @automattic/studio-cli. The existing Electron-bundled build (vite.config.ts) is unchanged.
- Remove unused `main` field (CLI-only package) - Include source maps in `files` whitelist - Use `npx --no-install` for deterministic postinstall
59e0919 to
b8819dc
Compare
Related issues
In this PR I am proposing to add a new CLI build - for now with manual package creation. As the next step I am planning to look into our organization npm access so we could manually publish it (privately-first) to npm under
@automattic/wp-studio- as we discussed in STU-1357.Then we can continue with making the publishing automated.
How AI was used in this PR
Claude Code implemented the plan from STU-1362 and iterated on build issues (externalized dependency resolution, shebang injection, ...) based on my feedback and manual testing. I have reviewed the whole generated code myself and with Copilot as well.
Proposed Changes
@automattic/wp-studiowith version, bin, files, engines, and publishConfig fields for npm publishingvite.config.npm.ts— a separate Vite config that externalizes runtime dependencies (npm handles them) and adds a#!/usr/bin/env nodeshebang to the main entry pointscripts/postinstall-npm.mjs— applies patches via patch-package after npm install (no-op in workspace context)vite.config.base.tsto reduce duplication between Electron and npm builds@studio/commondependencies at build time rather than listing them as runtime dependenciespackage.jsonfiles to use the new scoped package namecli:build:npmroot script for the npm buildTesting Instructions
node_modules/in npm build output and shebang is present:Pre-merge Checklist