Skip to content

Commit 55d74be

Browse files
committed
fix!: publishing prerelease requires tag
1 parent 75a3f12 commit 55d74be

File tree

2 files changed

+87
-0
lines changed

2 files changed

+87
-0
lines changed

lib/commands/publish.js

+7
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,13 @@ class Publish extends BaseCommand {
220220
Object.entries(manifest.publishConfig).filter(([key]) => !(key in cliFlags)))
221221
flatten(filteredPublishConfig, opts)
222222
}
223+
const isPreRelease = Boolean(semver.parse(manifest.version).prerelease.length)
224+
const isDefaultTag = this.npm.config.isDefault('tag')
225+
226+
if (isPreRelease && isDefaultTag) {
227+
throw new Error('You must specify a tag using --tag when publishing a prerelease version')
228+
}
229+
223230
return manifest
224231
}
225232
}

test/lib/commands/publish.js

+80
Original file line numberDiff line numberDiff line change
@@ -521,6 +521,7 @@ t.test('workspaces', t => {
521521
t.test('all workspaces - no color', async t => {
522522
const { npm, joinedOutput, logs } = await loadMockNpm(t, {
523523
config: {
524+
tag: 'latest',
524525
color: false,
525526
...auth,
526527
workspaces: true,
@@ -551,6 +552,7 @@ t.test('workspaces', t => {
551552
const { npm, joinedOutput, logs } = await loadMockNpm(t, {
552553
config: {
553554
...auth,
555+
tag: 'latest',
554556
color: 'always',
555557
workspaces: true,
556558
},
@@ -580,6 +582,7 @@ t.test('workspaces', t => {
580582
const { npm, joinedOutput } = await loadMockNpm(t, {
581583
config: {
582584
...auth,
585+
tag: 'latest',
583586
workspace: ['workspace-a'],
584587
},
585588
prefixDir: dir,
@@ -601,6 +604,7 @@ t.test('workspaces', t => {
601604
const { npm } = await loadMockNpm(t, {
602605
config: {
603606
...auth,
607+
tag: 'latest',
604608
workspace: ['workspace-a'],
605609
},
606610
prefixDir: dir,
@@ -642,6 +646,7 @@ t.test('workspaces', t => {
642646
const { npm, joinedOutput } = await loadMockNpm(t, {
643647
config: {
644648
...auth,
649+
tag: 'latest',
645650
workspaces: true,
646651
},
647652
prefixDir: testDir,
@@ -663,6 +668,7 @@ t.test('workspaces', t => {
663668
const { npm } = await loadMockNpm(t, {
664669
config: {
665670
...auth,
671+
tag: 'latest',
666672
workspace: ['workspace-x'],
667673
},
668674
prefixDir: dir,
@@ -677,6 +683,7 @@ t.test('workspaces', t => {
677683
const { npm, joinedOutput } = await loadMockNpm(t, {
678684
config: {
679685
...auth,
686+
tag: 'latest',
680687
workspaces: true,
681688
json: true,
682689
},
@@ -725,6 +732,7 @@ t.test('workspaces', t => {
725732
const { npm, joinedOutput } = await loadMockNpm(t, {
726733
config: {
727734
...auth,
735+
tag: 'latest',
728736
},
729737
prefixDir: testDir,
730738
chdir: ({ prefix }) => path.resolve(prefix, './workspace-a'),
@@ -988,3 +996,75 @@ t.test('manifest', async t => {
988996

989997
t.matchSnapshot(manifest, 'manifest')
990998
})
999+
1000+
t.test('aborts when prerelease and no tag', async t => {
1001+
const { npm } = await loadMockNpm(t, {
1002+
config: {
1003+
loglevel: 'silent',
1004+
[`${alternateRegistry.slice(6)}/:_authToken`]: 'test-other-token',
1005+
},
1006+
prefixDir: {
1007+
'package.json': JSON.stringify({
1008+
...pkgJson,
1009+
version: '1.0.0-0',
1010+
publishConfig: { registry: alternateRegistry },
1011+
}, null, 2),
1012+
},
1013+
})
1014+
1015+
await t.rejects(async () => {
1016+
await npm.exec('publish', [])
1017+
}, new Error('You must specify a tag using --tag when publishing a prerelease version'))
1018+
})
1019+
1020+
t.test('does not abort when prerelease and authored tag latest', async t => {
1021+
const prereleasePkg = {
1022+
...pkgJson,
1023+
version: '1.0.0-0',
1024+
}
1025+
const { npm } = await loadMockNpm(t, {
1026+
config: {
1027+
loglevel: 'silent',
1028+
tag: 'latest',
1029+
[`${alternateRegistry.slice(6)}/:_authToken`]: 'test-other-token',
1030+
},
1031+
prefixDir: {
1032+
'package.json': JSON.stringify({
1033+
...prereleasePkg,
1034+
publishConfig: { registry: alternateRegistry },
1035+
}, null, 2),
1036+
},
1037+
})
1038+
const registry = new MockRegistry({
1039+
tap: t,
1040+
registry: alternateRegistry,
1041+
authorization: 'test-other-token',
1042+
})
1043+
registry.nock.put(`/${pkg}`, body => {
1044+
return t.match(body, {
1045+
_id: pkg,
1046+
name: pkg,
1047+
'dist-tags': { latest: prereleasePkg.version },
1048+
access: null,
1049+
versions: {
1050+
[prereleasePkg.version]: {
1051+
name: pkg,
1052+
version: prereleasePkg.version,
1053+
_id: `${pkg}@${prereleasePkg.version}`,
1054+
dist: {
1055+
shasum: /\.*/,
1056+
// eslint-disable-next-line max-len
1057+
tarball: `http:${alternateRegistry.slice(6)}/test-package/-/test-package-${prereleasePkg.version}.tgz`,
1058+
},
1059+
publishConfig: {
1060+
registry: alternateRegistry,
1061+
},
1062+
},
1063+
},
1064+
_attachments: {
1065+
[`${pkg}-${prereleasePkg.version}.tgz`]: {},
1066+
},
1067+
})
1068+
}).reply(200, {})
1069+
await npm.exec('publish', [])
1070+
})

0 commit comments

Comments
 (0)