From e4c7a410f590e5c9c81f6410f600181a4deef005 Mon Sep 17 00:00:00 2001 From: milaninfy <111582375+milaninfy@users.noreply.github.com> Date: Wed, 29 May 2024 10:29:14 -0400 Subject: [PATCH] fix(publish): skip workspace packages marked private on publish (#7564) `npm publish --workspaces` will skip workspace packages marked as private in package.json. Currently it's skipping those packages only when you have configured auth for those packages, it would error out with `ENEEDAUTH` if it doesn't find the valid auth information. this fix checks for the private property before checking for auth for the packages that will essentially not going to get published. Fixes https://github.com/npm/cli/issues/7199 --- lib/commands/publish.js | 9 ++++ .../test/lib/commands/publish.js.test.cjs | 4 ++ test/lib/commands/publish.js | 42 +++++++++++++++++++ 3 files changed, 55 insertions(+) diff --git a/lib/commands/publish.js b/lib/commands/publish.js index 6f893b929284b..3fe337a7b1c43 100644 --- a/lib/commands/publish.js +++ b/lib/commands/publish.js @@ -127,6 +127,15 @@ class Publish extends BaseCommand { const noCreds = !(creds.token || creds.username || creds.certfile && creds.keyfile) const outputRegistry = replaceInfo(registry) + // if a workspace package is marked private then we skip it + if (workspace && manifest.private) { + throw Object.assign( + new Error(`This package has been marked as private + Remove the 'private' field from the package.json to publish it.`), + { code: 'EPRIVATE' } + ) + } + if (noCreds) { const msg = `This command requires you to be logged in to ${outputRegistry}` if (dryRun) { diff --git a/tap-snapshots/test/lib/commands/publish.js.test.cjs b/tap-snapshots/test/lib/commands/publish.js.test.cjs index c13834d5d694c..4c0cd05fe504d 100644 --- a/tap-snapshots/test/lib/commands/publish.js.test.cjs +++ b/tap-snapshots/test/lib/commands/publish.js.test.cjs @@ -418,6 +418,10 @@ Array [ ] ` +exports[`test/lib/commands/publish.js TAP workspaces all workspaces - some marked private > one marked private 1`] = ` ++ workspace-a@1.2.3-a +` + exports[`test/lib/commands/publish.js TAP workspaces json > all workspaces in json 1`] = ` { "workspace-a": { diff --git a/test/lib/commands/publish.js b/test/lib/commands/publish.js index a90d07d0ae572..fa43994679b97 100644 --- a/test/lib/commands/publish.js +++ b/test/lib/commands/publish.js @@ -617,6 +617,48 @@ t.test('workspaces', t => { await t.rejects(npm.exec('publish', []), { code: 'E404' }) }) + t.test('all workspaces - some marked private', async t => { + const testDir = { + 'package.json': JSON.stringify( + { + ...pkgJson, + workspaces: ['workspace-a', 'workspace-p'], + }, null, 2), + 'workspace-a': { + 'package.json': JSON.stringify({ + name: 'workspace-a', + version: '1.2.3-a', + }), + }, + 'workspace-p': { + 'package.json': JSON.stringify({ + name: '@scoped/workspace-p', + private: true, + version: '1.2.3-p-scoped', + }), + }, + } + + const { npm, joinedOutput } = await loadMockNpm(t, { + config: { + ...auth, + workspaces: true, + }, + prefixDir: testDir, + }) + const registry = new MockRegistry({ + tap: t, + registry: npm.config.get('registry'), + authorization: token, + }) + registry.nock + .put('/workspace-a', body => { + return t.match(body, { name: 'workspace-a' }) + }).reply(200, {}) + await npm.exec('publish', []) + t.matchSnapshot(joinedOutput(), 'one marked private') + }) + t.test('invalid workspace', async t => { const { npm } = await loadMockNpm(t, { config: {