Repository: semantic-release/npm
Pull request #55 (2018-03-07 22:39:28)

fix: fix error handling when no npm token is defined
Fix error in https://travis-ci.org/crystal-lang-tools/atom-ide-crystal/builds/350548591#L1331


Patch:
diff --git a/lib/definitions/errors.js b/lib/definitions/errors.js
index 45d6f38..9a52359 100644
--- a/lib/definitions/errors.js
+++ b/lib/definitions/errors.js
@@ -22,6 +22,14 @@ Your configuration for the \`tarballDir\` option is \`${tarballDir}\`.`,
     details: `The [pkgRoot option](${linkify('README.md#pkgroot')}) option, if defined, must be a \`String\`.
 
 Your configuration for the \`pkgRoot\` option is \`${pkgRoot}\`.`,
+  }),
+  ENONPMTOKEN: ({registry}) => ({
+    message: 'No npm token specified.',
+    details: `An [npm token](${linkify(
+      'README.md#npm-registry-authentication'
+    )}) must be created and set in the \`NPM_TOKEN\` environment variable on your CI environment.
+
+Please make sure to create an [npm token](https://docs.npmjs.com/getting-started/working_with_tokens#how-to-create-new-tokens) and to set it in the \`NPM_TOKEN\` environment variable on your CI environment. The token must allow to publish to the registry \`${registry}\`.`,
   }),
   EINVALIDNPMTOKEN: ({registry}) => ({
     message: 'Invalid npm token.',
@@ -33,7 +41,6 @@ If you are using Two-Factor Authentication, make configure the \`auth-only\` [le
 
 Please make sure to set the \`NPM_TOKEN\` environment variable in your CI with the exact value of the npm token.`,
   }),
-
   ENOPKGNAME: () => ({
     message: 'Missing `name` property in `package.json`.',
     details: `The \`package.json\`'s [name](https://docs.npmjs.com/files/package.json#name) property is required in order to publish a package to the npm registry.
diff --git a/lib/set-npmrc-auth.js b/lib/set-npmrc-auth.js
index f86e14b..dda54bd 100644
--- a/lib/set-npmrc-auth.js
+++ b/lib/set-npmrc-auth.js
@@ -1,7 +1,8 @@
 const {appendFile} = require('fs-extra');
 const getAuthToken = require('registry-auth-token');
 const nerfDart = require('nerf-dart');
-const SemanticReleaseError = require('@semantic-release/error');
+const AggregateError = require('aggregate-error');
+const getError = require('./get-error');
 
 module.exports = async (registry, logger) => {
   logger.log('Verify authentication for registry %s', registry);
@@ -17,6 +18,6 @@ module.exports = async (registry, logger) => {
     await appendFile('./.npmrc', `\n${nerfDart(registry)}:_authToken = \${NPM_TOKEN}`);
     logger.log('Wrote NPM_TOKEN to .npmrc.');
   } else {
-    throw new SemanticReleaseError('No npm token specified.', 'ENONPMTOKEN');
+    throw new AggregateError([getError('ENONPMTOKEN', {registry})]);
   }
 };


Test patch:
diff --git a/test/set-npmrc-auth.test.js b/test/set-npmrc-auth.test.js
index 2757735..428d072 100644
--- a/test/set-npmrc-auth.test.js
+++ b/test/set-npmrc-auth.test.js
@@ -68,7 +68,7 @@ test.serial('Do not modify ".npmrc" if auth is already configured for a scoped p
 });
 
 test.serial('Throw error if "NPM_TOKEN" is missing', async t => {
-  const error = await t.throws(setNpmrcAuth('http://custom.registry.com', t.context.logger));
+  const [error] = await t.throws(setNpmrcAuth('http://custom.registry.com', t.context.logger));
 
   t.is(error.name, 'SemanticReleaseError');
   t.is(error.message, 'No npm token specified.');
@@ -78,7 +78,7 @@ test.serial('Throw error if "NPM_TOKEN" is missing', async t => {
 test.serial('Throw error if "NPM_USERNAME" is missing', async t => {
   process.env.NPM_PASSWORD = 'npm_pasword';
   process.env.NPM_EMAIL = 'npm_email';
-  const error = await t.throws(setNpmrcAuth('http://custom.registry.com', t.context.logger));
+  const [error] = await t.throws(setNpmrcAuth('http://custom.registry.com', t.context.logger));
 
   t.is(error.name, 'SemanticReleaseError');
   t.is(error.message, 'No npm token specified.');
@@ -88,7 +88,7 @@ test.serial('Throw error if "NPM_USERNAME" is missing', async t => {
 test.serial('Throw error if "NPM_PASSWORD" is missing', async t => {
   process.env.NPM_USERNAME = 'npm_username';
   process.env.NPM_EMAIL = 'npm_email';
-  const error = await t.throws(setNpmrcAuth('http://custom.registry.com', t.context.logger));
+  const [error] = await t.throws(setNpmrcAuth('http://custom.registry.com', t.context.logger));
 
   t.is(error.name, 'SemanticReleaseError');
   t.is(error.message, 'No npm token specified.');
@@ -98,7 +98,7 @@ test.serial('Throw error if "NPM_PASSWORD" is missing', async t => {
 test.serial('Throw error if "NPM_EMAIL" is missing', async t => {
   process.env.NPM_USERNAME = 'npm_username';
   process.env.NPM_PASSWORD = 'npm_password';
-  const error = await t.throws(setNpmrcAuth('http://custom.registry.com', t.context.logger));
+  const [error] = await t.throws(setNpmrcAuth('http://custom.registry.com', t.context.logger));
 
   t.is(error.name, 'SemanticReleaseError');
   t.is(error.message, 'No npm token specified.');