Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions lib/commands/publish.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ class Publish extends BaseCommand {
'access',
'dry-run',
'otp',
'publish-registry',
'workspace',
'workspaces',
'include-workspace-root',
Expand Down Expand Up @@ -82,6 +83,10 @@ class Publish extends BaseCommand {
}

const opts = { ...this.npm.flatOptions, progress: false }
const publishRegistry = this.npm.config.get('publish-registry')
if (publishRegistry) {
opts.registry = publishRegistry
}

// you can publish name@version, ./foo.tgz, etc.
// even though the default is the 'file:.' cwd.
Expand Down
6 changes: 5 additions & 1 deletion lib/commands/unpublish.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ const LAST_REMAINING_VERSION_ERROR = 'Refusing to delete the last version of the
class Unpublish extends BaseCommand {
static description = 'Remove a package from the registry'
static name = 'unpublish'
static params = ['dry-run', 'force', 'workspace', 'workspaces']
static params = ['dry-run', 'force', 'publish-registry', 'workspace', 'workspaces']
static usage = ['[<package-spec>]']
static workspaces = true
static ignoreImplicitWorkspace = false
Expand Down Expand Up @@ -103,6 +103,10 @@ class Unpublish extends BaseCommand {
}

const opts = { ...this.npm.flatOptions }
const publishRegistry = this.npm.config.get('publish-registry')
if (publishRegistry) {
opts.registry = publishRegistry
}

let manifest
try {
Expand Down
8 changes: 8 additions & 0 deletions tap-snapshots/test/lib/commands/publish.js.test.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -288,10 +288,18 @@ exports[`test/lib/commands/publish.js TAP public access > new package version 1`
+ @npm/test-package@1.0.0
`

exports[`test/lib/commands/publish.js TAP publish-registry config overridden by publishConfig.registry > new package version 1`] = `
+ @npmcli/test-package@1.0.0
`

exports[`test/lib/commands/publish.js TAP re-loads publishConfig.registry if added during script process > new package version 1`] = `
+ @npmcli/test-package@1.0.0
`

exports[`test/lib/commands/publish.js TAP respects publish-registry config > new package version 1`] = `
+ @npmcli/test-package@1.0.0
`

exports[`test/lib/commands/publish.js TAP respects publishConfig.registry, runs appropriate scripts > new package version 1`] = `

> @npmcli/test-package@1.0.0 prepublishOnly
Expand Down
58 changes: 58 additions & 0 deletions test/lib/commands/publish.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,64 @@ t.test('respects publishConfig.registry, runs appropriate scripts', async t => {
t.same(logs.warn, ['Unknown publishConfig config "other". This will stop working in the next major version of npm. See `npm help npmrc` for supported config options.'])
})

t.test('respects publish-registry config', async t => {
const publishRegistry = alternateRegistry
const { joinedOutput, npm, registry } = await loadNpmWithRegistry(t, {
config: {
'publish-registry': publishRegistry,
[`${publishRegistry.slice(6)}/:_authToken`]: 'test-other-token',
},
prefixDir: {
'package.json': JSON.stringify(pkgJson, null, 2),
},
registry: publishRegistry,
authorization: 'test-other-token',
})
registry.getPackage(pkg, { times: 2, code: 404 })
registry.putPackage(pkg, { packageJson: pkgJson, registry: publishRegistry })
await npm.exec('publish', [])
t.matchSnapshot(joinedOutput(), 'new package version')
})

t.test('publish-registry config overridden by publishConfig.registry', async t => {
const publishRegistry = alternateRegistry
const thirdRegistry = 'https://third.registry.npmjs.org'
const packageJson = {
...pkgJson,
publishConfig: { registry: thirdRegistry },
}
const { joinedOutput, npm, registry } = await loadNpmWithRegistry(t, {
config: {
'publish-registry': publishRegistry,
[`${thirdRegistry.slice(6)}/:_authToken`]: 'test-third-token',
},
prefixDir: {
'package.json': JSON.stringify(packageJson, null, 2),
},
registry: thirdRegistry,
authorization: 'test-third-token',
})
registry.publish(pkg, { packageJson })
await npm.exec('publish', [])
t.matchSnapshot(joinedOutput(), 'new package version')
})

t.test('publish-registry config does not affect install registry', async t => {
const publishRegistry = alternateRegistry
const { npm } = await loadNpmWithRegistry(t, {
config: {
'publish-registry': publishRegistry,
...auth,
},
prefixDir: {
'package.json': JSON.stringify(pkgJson, null, 2),
},
authorization: token,
})
t.equal(npm.config.get('registry'), 'https://registry.npmjs.org/')
t.equal(npm.config.get('publish-registry'), alternateRegistry + '/')
})

t.test('re-loads publishConfig.registry if added during script process', async t => {
const initPackageJson = {
...pkgJson,
Expand Down
28 changes: 28 additions & 0 deletions test/lib/commands/unpublish.js
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,34 @@ t.test('dryRun with no args', async t => {
t.equal(joinedOutput(), '- test-package@1.0.0')
})

t.test('publish-registry config', async t => {
const alternateRegistry = 'https://other.registry.npmjs.org'
const { joinedOutput, npm } = await loadMockNpm(t, {
config: {
force: true,
'publish-registry': alternateRegistry,
'//other.registry.npmjs.org/:_authToken': 'test-other-token',
},
prefixDir: {
'package.json': JSON.stringify({
name: pkg,
version: '1.0.0',
}, null, 2),
},
})

const registry = new MockRegistry({
tap: t,
registry: alternateRegistry,
authorization: 'test-other-token',
})
const manifest = registry.manifest({ name: pkg })
await registry.package({ manifest, query: { write: true }, times: 2 })
registry.unpublish({ manifest })
await npm.exec('unpublish', [])
t.equal(joinedOutput(), '- test-package')
})

t.test('publishConfig no spec', async t => {
const alternateRegistry = 'https://other.registry.npmjs.org'
const { logs, joinedOutput, npm } = await loadMockNpm(t, {
Expand Down
11 changes: 11 additions & 0 deletions workspaces/config/lib/definitions/definitions.js
Original file line number Diff line number Diff line change
Expand Up @@ -1726,6 +1726,17 @@ const definitions = {
`,
flatten,
}),
'publish-registry': new Definition('publish-registry', {
default: null,
type: [null, url],
description: `
The base URL of the npm registry to use for \`npm publish\` and
\`npm unpublish\`. When set, overrides \`registry\` for these
commands while leaving \`registry\` in effect for all other
operations like install and view.
`,
flatten,
}),
registry: new Definition('registry', {
default: 'https://registry.npmjs.org/',
type: url,
Expand Down
Loading