Skip to content

Commit 4cd5cd7

Browse files
pvdlggr2m
authored andcommitted
fix: skip npm auth verification if npmPublish is false
1 parent 49e2e2b commit 4cd5cd7

File tree

5 files changed

+91
-23
lines changed

5 files changed

+91
-23
lines changed

index.js

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,17 @@
11
const {castArray} = require('lodash');
22
const setLegacyToken = require('./lib/set-legacy-token');
33
const getPkg = require('./lib/get-pkg');
4-
const verifyNpm = require('./lib/verify');
4+
const verifyNpmConfig = require('./lib/verify-config');
5+
const verifyNpmAuth = require('./lib/verify-auth');
56
const publishNpm = require('./lib/publish');
67
const getLastReleaseNpm = require('./lib/get-last-release');
78

89
let verified;
910

10-
async function verifyConditions(pluginConfig, {options, logger}) {
11+
async function verifyConditions(pluginConfig, {options: {publish, getLastRelease}, logger}) {
1112
// If the npm publish plugin is used and has `npmPublish`, `tarballDir` or `pkgRoot` configured, validate them now in order to prevent any release if the configuration is wrong
12-
if (options.publish) {
13-
const publishPlugin = castArray(options.publish).find(
14-
config => config.path && config.path === '@semantic-release/npm'
15-
);
13+
if (publish) {
14+
const publishPlugin = castArray(publish).find(config => config.path && config.path === '@semantic-release/npm');
1615
if (publishPlugin && publishPlugin.npmPublish) {
1716
pluginConfig.npmPublish = publishPlugin.npmPublish;
1817
}
@@ -23,9 +22,18 @@ async function verifyConditions(pluginConfig, {options, logger}) {
2322
pluginConfig.pkgRoot = publishPlugin.pkgRoot;
2423
}
2524
}
26-
setLegacyToken();
25+
2726
const pkg = await getPkg(pluginConfig.pkgRoot);
28-
await verifyNpm(pluginConfig, pkg, logger);
27+
await verifyNpmConfig(pluginConfig, pkg, logger);
28+
29+
// Verify the npm authentication only if `npmPublish` is not false and if the npm plugin is used as `getLastRelease`
30+
if (
31+
pluginConfig.npmPublish !== false ||
32+
(getLastRelease && (getLastRelease === '@semantic-release/npm' || getLastRelease.path === '@semantic-release/npm'))
33+
) {
34+
setLegacyToken();
35+
await verifyNpmAuth(pluginConfig, pkg, logger);
36+
}
2937
verified = true;
3038
}
3139

@@ -42,7 +50,8 @@ async function getLastRelease(pluginConfig, {options, logger}) {
4250
pluginConfig.pkgRoot = publishPlugin.pkgRoot;
4351
}
4452
}
45-
await verifyNpm(pluginConfig, pkg, logger);
53+
await verifyNpmConfig(pluginConfig, pkg, logger);
54+
await verifyNpmAuth(pluginConfig, pkg, logger);
4655
verified = true;
4756
}
4857
return getLastReleaseNpm(pkg, logger);
@@ -53,7 +62,8 @@ async function publish(pluginConfig, {nextRelease: {version}, logger}) {
5362
// Reload package.json in case a previous external step updated it
5463
const pkg = await getPkg(pluginConfig.pkgRoot);
5564
if (!verified) {
56-
await verifyNpm(pluginConfig, pkg, logger);
65+
await verifyNpmConfig(pluginConfig, pkg, logger);
66+
await verifyNpmAuth(pluginConfig, pkg, logger);
5767
verified = true;
5868
}
5969
await publishNpm(pluginConfig, pkg, version, logger);

lib/verify-auth.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
const execa = require('execa');
2+
const SemanticReleaseError = require('@semantic-release/error');
3+
const getRegistry = require('./get-registry');
4+
const setNpmrcAuth = require('./set-npmrc-auth');
5+
6+
module.exports = async (pluginConfig, pkg, logger) => {
7+
const registry = await getRegistry(pkg.publishConfig, pkg.name);
8+
await setNpmrcAuth(registry, logger);
9+
try {
10+
await execa('npm', ['whoami', '--registry', registry]);
11+
} catch (err) {
12+
throw new SemanticReleaseError('Invalid npm token.', 'EINVALIDNPMTOKEN');
13+
}
14+
};
Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
11
const {isString, isUndefined, isBoolean} = require('lodash');
2-
const execa = require('execa');
32
const SemanticReleaseError = require('@semantic-release/error');
4-
const getRegistry = require('./get-registry');
5-
const setNpmrcAuth = require('./set-npmrc-auth');
63

7-
module.exports = async ({npmPublish, tarballDir, pkgRoot}, pkg, logger) => {
4+
module.exports = async ({npmPublish, tarballDir, pkgRoot}) => {
85
if (!isUndefined(npmPublish) && !isBoolean(npmPublish)) {
96
throw new SemanticReleaseError('The "npmPublish" options, if defined, must be a Boolean.', 'EINVALIDNPMPUBLISH');
107
}
@@ -16,12 +13,4 @@ module.exports = async ({npmPublish, tarballDir, pkgRoot}, pkg, logger) => {
1613
if (!isUndefined(pkgRoot) && !isString(pkgRoot)) {
1714
throw new SemanticReleaseError('The "pkgRoot" options, if defined, must be a String.', 'EINVALIDPKGROOT');
1815
}
19-
20-
const registry = await getRegistry(pkg.publishConfig, pkg.name);
21-
await setNpmrcAuth(registry, logger);
22-
try {
23-
await execa('npm', ['whoami', '--registry', registry]);
24-
} catch (err) {
25-
throw new SemanticReleaseError('Invalid npm token.', 'EINVALIDNPMTOKEN');
26-
}
2716
};

test/integration.test.js

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,13 @@ test.after.always(async () => {
4848
await npmRegistry.stop();
4949
});
5050

51+
test.serial('Skip npm auth verification if "npmPublish" is false', async t => {
52+
process.env.NPM_TOKEN = 'wrong_token';
53+
const pkg = {name: 'published', version: '1.0.0', publishConfig: {registry: npmRegistry.url}};
54+
await outputJson('./package.json', pkg);
55+
await t.notThrows(t.context.m.verifyConditions({npmPublish: false}, {options: {}, logger: t.context.logger}));
56+
});
57+
5158
test.serial('Throws error if NPM token is invalid', async t => {
5259
process.env.NPM_TOKEN = 'wrong_token';
5360
const pkg = {name: 'published', version: '1.0.0', publishConfig: {registry: npmRegistry.url}};
@@ -62,6 +69,50 @@ test.serial('Throws error if NPM token is invalid', async t => {
6269
t.regex(npmrc, /:_authToken/);
6370
});
6471

72+
test.serial(
73+
'Throws error if NPM token is invalid if "npmPublish" is false and npm plugin used for "getLastRelease"',
74+
async t => {
75+
process.env.NPM_TOKEN = 'wrong_token';
76+
const pkg = {name: 'published', version: '1.0.0', publishConfig: {registry: npmRegistry.url}};
77+
await outputJson('./package.json', pkg);
78+
const error = await t.throws(
79+
t.context.m.verifyConditions(
80+
{npmPublish: false},
81+
{options: {getLastRelease: '@semantic-release/npm'}, logger: t.context.logger}
82+
)
83+
);
84+
85+
t.true(error instanceof SemanticReleaseError);
86+
t.is(error.code, 'EINVALIDNPMTOKEN');
87+
t.is(error.message, 'Invalid npm token.');
88+
89+
const npmrc = (await readFile('.npmrc')).toString();
90+
t.regex(npmrc, /:_authToken/);
91+
}
92+
);
93+
94+
test.serial(
95+
'Throws error if NPM token is invalid if "npmPublish" is false and npm plugin used for "getLastRelease" as an object',
96+
async t => {
97+
process.env.NPM_TOKEN = 'wrong_token';
98+
const pkg = {name: 'published', version: '1.0.0', publishConfig: {registry: npmRegistry.url}};
99+
await outputJson('./package.json', pkg);
100+
const error = await t.throws(
101+
t.context.m.verifyConditions(
102+
{npmPublish: false},
103+
{options: {getLastRelease: {path: '@semantic-release/npm'}}, logger: t.context.logger}
104+
)
105+
);
106+
107+
t.true(error instanceof SemanticReleaseError);
108+
t.is(error.code, 'EINVALIDNPMTOKEN');
109+
t.is(error.message, 'Invalid npm token.');
110+
111+
const npmrc = (await readFile('.npmrc')).toString();
112+
t.regex(npmrc, /:_authToken/);
113+
}
114+
);
115+
65116
test.serial('Verify npm auth and package', async t => {
66117
Object.assign(process.env, npmRegistry.authEnv);
67118
const pkg = {name: 'valid-token', publishConfig: {registry: npmRegistry.url}};
Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,17 @@
11
import test from 'ava';
22
import {stub} from 'sinon';
3-
import verify from '../lib/verify';
3+
import verify from '../lib/verify-config';
44

55
test.beforeEach(t => {
66
// Stub the logger functions
77
t.context.log = stub();
88
t.context.logger = {log: t.context.log};
99
});
1010

11+
test('Verify "npmPublish", "tarballDir" and "pkgRoot" options', async t => {
12+
await t.notThrows(verify({npmPublish: true, tarballDir: 'release', pkgRoot: 'dist'}, {}, t.context.logger));
13+
});
14+
1115
test('Throw SemanticReleaseError if "npmPublish" option is not a Boolean', async t => {
1216
const npmPublish = 42;
1317
const error = await t.throws(verify({npmPublish}, {}, t.context.logger));

0 commit comments

Comments
 (0)