Skip to content

Commit

Permalink
fix(publish): accept publishConfig.tag to override highes semver check
Browse files Browse the repository at this point in the history
Setting `tag` in `publishConfig` constitutes a "non default" scenario.
  • Loading branch information
wraithgar committed Jan 17, 2025
1 parent 7e7961d commit 7f72944
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 34 deletions.
6 changes: 3 additions & 3 deletions lib/commands/publish.js
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ class Publish extends BaseCommand {
manifest = await this.#getManifest(spec, opts, true)

const isPreRelease = Boolean(semver.parse(manifest.version).prerelease.length)
const isDefaultTag = this.npm.config.isDefault('tag')
const isDefaultTag = this.npm.config.isDefault('tag') && !manifest.publishConfig?.tag

if (isPreRelease && isDefaultTag) {
throw new Error('You must specify a tag using --tag when publishing a prerelease version.')
Expand Down Expand Up @@ -157,7 +157,7 @@ class Publish extends BaseCommand {
}
}

const latestVersion = await this.#latestPublishedVersion(resolved, registry)
const latestVersion = await this.#highestPublishedVersion(resolved, registry)
const latestSemverIsGreater = !!latestVersion && semver.gte(latestVersion, manifest.version)

if (latestSemverIsGreater && isDefaultTag) {
Expand Down Expand Up @@ -204,7 +204,7 @@ class Publish extends BaseCommand {
}
}

async #latestPublishedVersion (spec, registry) {
async #highestPublishedVersion (spec, registry) {
try {
const packument = await pacote.packument(spec, {
...this.npm.flatOptions,
Expand Down
28 changes: 14 additions & 14 deletions tap-snapshots/test/lib/commands/publish.js.test.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
*/
'use strict'
exports[`test/lib/commands/publish.js TAP _auth config default registry > new package version 1`] = `
+ test-package@1.0.0
+ @npmcli/test-package@1.0.0
`

exports[`test/lib/commands/publish.js TAP bare _auth and registry config > new package version 1`] = `
Expand All @@ -15,15 +15,15 @@ exports[`test/lib/commands/publish.js TAP bare _auth and registry config > new p

exports[`test/lib/commands/publish.js TAP dry-run > must match snapshot 1`] = `
Array [
"package: test-package@1.0.0",
"package: @npmcli/test-package@1.0.0",
"Tarball Contents",
"87B package.json",
"95B package.json",
"Tarball Details",
"name: test-package",
"name: @npmcli/test-package",
"version: 1.0.0",
"filename: test-package-1.0.0.tgz",
"filename: npmcli-test-package-1.0.0.tgz",
"package size: {size}",
"unpacked size: 87 B",
"unpacked size: 95 B",
"shasum: {sha}",
"integrity: {integrity}
"total files: 1",
Expand Down Expand Up @@ -76,7 +76,7 @@ exports[`test/lib/commands/publish.js TAP has token auth for scope configured re
`

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

exports[`test/lib/commands/publish.js TAP json > must match snapshot 1`] = `
Expand All @@ -87,14 +87,14 @@ Array [

exports[`test/lib/commands/publish.js TAP json > new package json 1`] = `
{
"id": "test-package@1.0.0",
"name": "test-package",
"id": "@npmcli/test-package@1.0.0",
"name": "@npmcli/test-package",
"version": "1.0.0",
"size": "{size}",
"unpackedSize": 87,
"unpackedSize": 95,
"shasum": "{sha}",
"integrity": "{integrity}",
"filename": "test-package-1.0.0.tgz",
"filename": "npmcli-test-package-1.0.0.tgz",
"files": [
{
"path": "package.json",
Expand Down Expand Up @@ -249,7 +249,7 @@ Object {
`

exports[`test/lib/commands/publish.js TAP no auth dry-run > must match snapshot 1`] = `
+ test-package@1.0.0
+ @npmcli/test-package@1.0.0
`

exports[`test/lib/commands/publish.js TAP no auth dry-run > warns about auth being needed 1`] = `
Expand All @@ -259,7 +259,7 @@ Array [
`

exports[`test/lib/commands/publish.js TAP prioritize CLI flags over publishConfig > new package version 1`] = `
+ test-package@1.0.0
+ @npmcli/test-package@1.0.0
`

exports[`test/lib/commands/publish.js TAP public access > must match snapshot 1`] = `
Expand All @@ -285,7 +285,7 @@ exports[`test/lib/commands/publish.js TAP public access > new package version 1`
`

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

exports[`test/lib/commands/publish.js TAP respects publishConfig.registry, runs appropriate scripts > new package version 1`] = `
Expand Down
45 changes: 28 additions & 17 deletions test/lib/commands/publish.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ const Arborist = require('@npmcli/arborist')
const path = require('node:path')
const fs = require('node:fs')

const pkg = 'test-package'
const pkg = '@npmcli/test-package'
const token = 'test-auth-token'
const auth = { '//registry.npmjs.org/:_authToken': token }
const alternateRegistry = 'https://other.registry.npmjs.org'
Expand Down Expand Up @@ -238,8 +238,7 @@ t.test('throws when invalid tag when not url encodable', async t => {
await t.rejects(
npm.exec('publish', []),
{
/* eslint-disable-next-line max-len */
message: 'Invalid tag name "@test" of package "test-package@@test": Tags may not have any characters that encodeURIComponent encodes.',
message: `Invalid tag name "@test" of package "${pkg}@@test": Tags may not have any characters that encodeURIComponent encodes.`,
}
)
})
Expand Down Expand Up @@ -857,15 +856,16 @@ t.test('prerelease dist tag', (t) => {
t.end()
})

t.test('latest dist tag', (t) => {
const init = (version) => ({
t.test('semver highest dist tag', async t => {
const init = ({ version, pkgExtra = {} }) => ({
config: {
loglevel: 'silent',
...auth,
},
prefixDir: {
'package.json': JSON.stringify({
...pkgJson,
...pkgExtra,
version,
}, null, 2),
},
Expand All @@ -879,46 +879,57 @@ t.test('latest dist tag', (t) => {
{ version: '105.0.0-pre' },
]

t.test('PREVENTS publish when latest version is HIGHER than publishing version', async t => {
await t.test('PREVENTS publish when highest version is HIGHER than publishing version', async t => {
const version = '99.0.0'
const { npm, registry } = await loadNpmWithRegistry(t, init(version))
const { npm, registry } = await loadNpmWithRegistry(t, init({ version }))
registry.publish(pkg, { noPut: true, packuments })
await t.rejects(async () => {
await npm.exec('publish', [])
/* eslint-disable-next-line max-len */
}, new Error('Cannot implicitly apply the "latest" tag because published version 100.0.0 is higher than the new version 99.0.0. You must specify a tag using --tag.'))
})

t.test('ALLOWS publish when latest is HIGHER than publishing version and flag', async t => {
await t.test('ALLOWS publish when highest is HIGHER than publishing version and flag', async t => {
const version = '99.0.0'
const { npm, registry } = await loadNpmWithRegistry(t, {
...init(version),
...init({ version }),
argv: ['--tag', 'latest'],
})
registry.publish(pkg, { packuments })
await npm.exec('publish', [])
})

t.test('ALLOWS publish when latest versions are LOWER than publishing version', async t => {
await t.test('ALLOWS publish when highest versions are LOWER than publishing version', async t => {
const version = '101.0.0'
const { npm, registry } = await loadNpmWithRegistry(t, init(version))
const { npm, registry } = await loadNpmWithRegistry(t, init({ version }))
registry.publish(pkg, { packuments })
await npm.exec('publish', [])
})

t.test('ALLOWS publish when packument has empty versions (for coverage)', async t => {
await t.test('ALLOWS publish when packument has empty versions (for coverage)', async t => {
const version = '1.0.0'
const { npm, registry } = await loadNpmWithRegistry(t, init(version))
const { npm, registry } = await loadNpmWithRegistry(t, init({ version }))
registry.publish(pkg, { manifest: { versions: { } } })
await npm.exec('publish', [])
})

t.test('ALLOWS publish when packument has empty manifest (for coverage)', async t => {
await t.test('ALLOWS publish when packument has empty manifest (for coverage)', async t => {
const version = '1.0.0'
const { npm, registry } = await loadNpmWithRegistry(t, init(version))
const { npm, registry } = await loadNpmWithRegistry(t, init({ version }))
registry.publish(pkg, { manifest: {} })
await npm.exec('publish', [])
})

t.end()
await t.test('ALLOWS publish when highest version is HIGHER than publishing version with publishConfig', async t => {
const version = '99.0.0'
const { npm, registry } = await loadNpmWithRegistry(t, init({
version,
pkgExtra: {
publishConfig: {
tag: 'next',
},
},
}))
registry.publish(pkg, { packuments })
await npm.exec('publish', [])
})
})

0 comments on commit 7f72944

Please sign in to comment.