Publishing @mycli-cli/cli
MyCLI uses Changesets for version management and npm publishing.
Prerequisites
- npm account with publish access to the
@mycli-cliscope (org name must bemycli-cli) NPM_TOKENset in CI (GitHub Actions secret) for automated releases- All packages built:
pnpm build
Local release (maintainers)
1. Add a changeset when shipping user-facing changes:
``bash pnpm changeset ``
Select affected packages (typically @mycli-cli/cli and any updated managers), choose semver bump, and write a summary.
2. Version packages (updates package.json versions and changelog):
``bash pnpm version-packages ``
3. Publish to npm:
``bash pnpm release ``
This runs pnpm build then changeset publish.
CI release
The repository includes .github/workflows/release.yml. On every push to main it:
1. Runs pnpm install --frozen-lockfile 2. Runs pnpm build 3. Uses changesets/action with NPM_TOKEN
The action opens a “Version packages” PR when changesets exist; merging that PR triggers pnpm release (pnpm build && changeset publish).
Required secrets
| Secret | Purpose | |--------|---------| | NPM_TOKEN | npm Automation token with publish access to @mycli-cli/* (not a classic token that requires OTP) | | GITHUB_TOKEN | Provided by Actions — used to open version PRs |
The Release workflow writes auth to $HOME/.npmrc (user-level). pnpm ignores _authToken with ${…} expansion in a project .npmrc for security — that caused ERR_PNPM_OTP_NON_INTERACTIVE when CI wrote the token into the repo .npmrc.
Fixing ERR_PNPM_OTP_NON_INTERACTIVE / user undefined
If logs say user undefined or rate limited exceeded as user undefined, CI is publishing without login. That is not a package bug — auth never attached.
1. npmjs.com → Access Tokens → Generate New Token → type Automation (required; Classic + 2FA needs OTP and fails in CI) 2. Permission: read + write for @mycli-cli packages / org 3. GitHub repo → Settings → Secrets → Actions → set NPM_TOKEN to that token 4. Commit/push the Release workflow that writes the expanded token to $HOME/.npmrc and .npmrc (never a literal ${NPM_TOKEN} string in the file) 5. Re-run Release only after npm whoami succeeds in the workflow step
Fixing E429 (Too Many Requests)
Anonymous / failed-auth publishes burn the public rate limit quickly (user undefined). Wait 30–60 minutes, fix auth first, then re-run once. Do not keep re-running while auth is broken.
Fixing E404 on PUT https://registry.npmjs.org/@mycli-cli%2f…
npm returns 404 (not 403) when the token cannot publish to that scope. Check:
1. Org exists as mycli-cli: https://www.npmjs.com/settings/~/organizations 2. You are an Owner of that org 3. Token is Automation (or Granular with write to @mycli-cli packages) from the same account 4. GitHub secret is named exactly NPM_TOKEN 5. Re-run the Release workflow after fixing token/org
Local check:
npm whoami
npm org ls mycli-cli
Publishing official plugins
Official plugins live under plugins/official/ as @mycli-cli/plugin- packages. They are not in the default Changesets linked group (only core CLI packages are linked today).
To publish plugins:
1. Ensure the plugin package.json has "publishConfig": { "access": "public" } and is not "private": true. 2. Add a changeset selecting the plugin package(s) you changed. 3. Run the normal version-packages → merge PR → release flow.
Plugins are loaded at runtime when users run my plugin add <name>; publishing them to npm makes installation work outside the monorepo:
npm install -g @mycli-cli/plugin-postgres
my plugin add postgres
For local development, plugins resolve from the workspace via pnpm build without publishing.
Documentation site (public pages, private platform)
The full platform monorepo (my-cli) stays private.
Public docs/landing live in a separate repo: Rutvik-sonani/mycli-cli Live site: https://rutvik-sonani.github.io/mycli-cli/
Build locally:
pnpm --filter @mycli-cli/website build
# output: apps/website/dist
CI (.github/workflows/docs.yml) builds the site in the private monorepo and publishes only apps/website/dist to mycli-cli branch gh-pages.
One-time setup (secure deploy key)
CI uses a random ed25519 SSH deploy key (not a broad PAT):
1. Keep my-cli private; keep mycli-cli public (docs-only). 2. On private my-cli: secret ACTIONS_DEPLOY_KEY = deploy key private half. 3. On public mycli-cli: Deploy keys → add the matching public key with Allow write access. 4. On mycli-cli: Settings → Pages → Deploy from a branch → gh-pages / root. 5. Push to main on my-cli (or run Docs workflow) to publish.
Do not commit key material. Local generation lives under .tmp-secrets/ (gitignored).
Verify before publish
pnpm build
pnpm --filter @mycli-cli/cli test
pnpm e2e:generated
Fix broken workspace:* installs
If npm install -g @mycli-cli/cli fails with EUNSUPPORTEDPROTOCOL workspace:*, packages were published without rewriting monorepo deps.
Fix / republish (from repo root, interactive terminal for npm OTP):
pnpm build
node scripts/publish-fixed-packages.mjs
# enters OTP when prompted; publishes packages@1.0.2 and CLI@1.0.3
# with workspace:* rewritten to real versions
Dry-run (bump check only; still bumps versions if needed):
node scripts/publish-fixed-packages.mjs --dry-run
Then verify:
npm view @mycli-cli/cli-engine@1.0.2 dependencies
# must NOT contain workspace:*
npm install -g @mycli-cli/cli@1.0.3
my --version
Install for end users
After publish:
npm install -g @mycli-cli/cli
my create my-app --yes
Generated apps are scaffolds — configure env, database, and mail before production deploy. See ENVIRONMENT.md in generated projects.