From b8deba79479e4e9b49150d97311f43e42a5f9dd4 Mon Sep 17 00:00:00 2001 From: Pierre Vanduynslager Date: Thu, 28 Jun 2018 01:42:44 -0400 Subject: [PATCH] feat: support `nextRelease.channel` property in `publish` step --- lib/get-channel.js | 3 ++ lib/get-release-info.js | 21 +++-------- lib/publish.js | 8 ++-- package.json | 3 +- test/get-channel.test.js | 15 ++++++++ test/get-release-info.test.js | 71 ++--------------------------------- test/integration.test.js | 12 ++++-- 7 files changed, 43 insertions(+), 90 deletions(-) create mode 100644 lib/get-channel.js create mode 100644 test/get-channel.test.js diff --git a/lib/get-channel.js b/lib/get-channel.js new file mode 100644 index 00000000..8ca2e3c6 --- /dev/null +++ b/lib/get-channel.js @@ -0,0 +1,3 @@ +const semver = require('semver'); + +module.exports = channel => (channel ? (semver.validRange(channel) ? `release-${channel}` : channel) : 'latest'); diff --git a/lib/get-release-info.js b/lib/get-release-info.js index 6955088a..5956acb6 100644 --- a/lib/get-release-info.js +++ b/lib/get-release-info.js @@ -1,18 +1,7 @@ -const execa = require('execa'); const normalizeUrl = require('normalize-url'); -module.exports = async ( - {name, publishConfig: {tag} = {}}, - {cwd, env: {DEFAULT_NPM_REGISTRY = 'https://registry.npmjs.org/', ...env}}, - registry -) => { - const distTag = tag || (await execa.stdout('npm', ['config', 'get', 'tag'], {cwd, env})) || 'latest'; - - return { - name: `npm package (@${distTag} dist-tag)`, - url: - normalizeUrl(registry) === normalizeUrl(DEFAULT_NPM_REGISTRY) - ? `https://www.npmjs.com/package/${name}` - : undefined, - }; -}; +module.exports = async ({name}, {env: {DEFAULT_NPM_REGISTRY = 'https://registry.npmjs.org/'}}, distTag, registry) => ({ + name: `npm package (@${distTag} dist-tag)`, + url: + normalizeUrl(registry) === normalizeUrl(DEFAULT_NPM_REGISTRY) ? `https://www.npmjs.com/package/${name}` : undefined, +}); diff --git a/lib/publish.js b/lib/publish.js index b89bf48d..f5a634eb 100644 --- a/lib/publish.js +++ b/lib/publish.js @@ -1,6 +1,7 @@ const path = require('path'); const execa = require('execa'); const getRegistry = require('./get-registry'); +const getChannel = require('./get-channel'); const getReleaseInfo = require('./get-release-info'); module.exports = async ({npmPublish, pkgRoot}, pkg, context) => { @@ -9,16 +10,17 @@ module.exports = async ({npmPublish, pkgRoot}, pkg, context) => { env, stdout, stderr, - nextRelease: {version}, + nextRelease: {version, channel}, logger, } = context; if (npmPublish !== false && pkg.private !== true) { const basePath = pkgRoot ? path.resolve(cwd, pkgRoot) : cwd; const registry = getRegistry(pkg, context); + const distTag = getChannel(channel); logger.log('Publishing version %s to npm registry', version); - const result = execa('npm', ['publish', basePath, '--registry', registry], { + const result = execa('npm', ['publish', basePath, '--tag', distTag, '--registry', registry], { cwd, env, }); @@ -33,7 +35,7 @@ module.exports = async ({npmPublish, pkgRoot}, pkg, context) => { await result; logger.log(`Published ${pkg.name}@${pkg.version} on ${registry}`); - return getReleaseInfo(pkg, context, registry); + return getReleaseInfo(pkg, context, distTag, registry); } logger.log( 'Skip publishing to npm registry as %s is %s', diff --git a/package.json b/package.json index 29fe8bff..859c431f 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,8 @@ "npm": "^6.3.0", "rc": "^1.2.8", "read-pkg": "^4.0.0", - "registry-auth-token": "^3.3.1" + "registry-auth-token": "^3.3.1", + "semver": "^5.5.0" }, "devDependencies": { "ava": "^0.25.0", diff --git a/test/get-channel.test.js b/test/get-channel.test.js new file mode 100644 index 00000000..45be2522 --- /dev/null +++ b/test/get-channel.test.js @@ -0,0 +1,15 @@ +import test from 'ava'; +import getChannel from '../lib/get-channel'; + +test.serial('Get default channel', t => { + t.is(getChannel(undefined), 'latest'); +}); + +test.serial('Get passed channel if valid', t => { + t.is(getChannel('next'), 'next'); +}); + +test.serial('Prefix channel with "release-" if invalid', t => { + t.is(getChannel('1.x'), 'release-1.x'); + t.is(getChannel('1.0.0'), 'release-1.0.0'); +}); diff --git a/test/get-release-info.test.js b/test/get-release-info.test.js index 575307a1..2ff2690f 100644 --- a/test/get-release-info.test.js +++ b/test/get-release-info.test.js @@ -1,79 +1,16 @@ -import path from 'path'; import test from 'ava'; -import {writeFile} from 'fs-extra'; -import tempy from 'tempy'; import getReleaseInfo from '../lib/get-release-info'; -test.beforeEach(() => { - // Delete all `npm_config` environment variable set by CI as they take precedence over the `.npmrc` because the process that runs the tests is started before the `.npmrc` is created - for (let i = 0, keys = Object.keys(process.env); i < keys.length; i++) { - if (keys[i].startsWith('npm_')) { - delete process.env[keys[i]]; - } - } -}); - -test('Default registry and tag', async t => { - const cwd = tempy.directory(); - - t.deepEqual(await getReleaseInfo({name: 'module'}, {cwd, env: {}}, 'https://registry.npmjs.org/'), { - name: 'npm package (@latest dist-tag)', - url: 'https://www.npmjs.com/package/module', - }); -}); - -test('Default registry, tag and scoped module', async t => { - const cwd = tempy.directory(); - - t.deepEqual(await getReleaseInfo({name: '@scope/module'}, {cwd, env: {}}, 'https://registry.npmjs.org/'), { +test('Default registry and scoped module', async t => { + t.deepEqual(await getReleaseInfo({name: '@scope/module'}, {env: {}}, 'latest', 'https://registry.npmjs.org/'), { name: 'npm package (@latest dist-tag)', url: 'https://www.npmjs.com/package/@scope/module', }); }); -test('Custom registry, tag and scoped module', async t => { - const cwd = tempy.directory(); - - t.deepEqual(await getReleaseInfo({name: '@scope/module'}, {cwd, env: {}}, 'https://custom.registry.org/'), { +test('Custom registry and scoped module', async t => { + t.deepEqual(await getReleaseInfo({name: '@scope/module'}, {env: {}}, 'latest', 'https://custom.registry.org/'), { name: 'npm package (@latest dist-tag)', url: undefined, }); }); - -test('Default registry and tag from .npmrc', async t => { - const cwd = tempy.directory(); - await writeFile(path.resolve(cwd, '.npmrc'), 'tag=npmrc'); - - t.deepEqual( - await getReleaseInfo({name: 'module', publishConfig: {}}, {cwd, env: {}}, 'https://registry.npmjs.org/'), - { - name: 'npm package (@npmrc dist-tag)', - url: 'https://www.npmjs.com/package/module', - } - ); -}); - -test('Default registry and tag from package.json', async t => { - const cwd = tempy.directory(); - - await writeFile(path.resolve(cwd, '.npmrc'), 'tag=npmrc'); - - t.deepEqual( - await getReleaseInfo({name: 'module', publishConfig: {tag: 'pkg'}}, {cwd, env: {}}, 'https://registry.npmjs.org/'), - {name: 'npm package (@pkg dist-tag)', url: 'https://www.npmjs.com/package/module'} - ); -}); - -test('Default tag', async t => { - const cwd = tempy.directory(); - - await writeFile(path.resolve(cwd, '.npmrc'), 'tag='); - - t.deepEqual( - await getReleaseInfo({name: 'module', publishConfig: {}}, {cwd, env: {}}, 'https://registry.npmjs.org/'), - { - name: 'npm package (@latest dist-tag)', - url: 'https://www.npmjs.com/package/module', - } - ); -}); diff --git a/test/integration.test.js b/test/integration.test.js index 5faa6f37..49633e2d 100644 --- a/test/integration.test.js +++ b/test/integration.test.js @@ -275,7 +275,7 @@ test('Publish the package on a dist-tag', async t => { stdout: t.context.stdout, stderr: t.context.stderr, logger: t.context.logger, - nextRelease: {version: '1.0.0'}, + nextRelease: {channel: 'next', version: '1.0.0'}, } ); @@ -556,7 +556,7 @@ test('Verify token and set up auth only on the fist call, then prepare on prepar } ); - const result = await t.context.m.publish( + let result = await t.context.m.publish( {}, { cwd, @@ -565,8 +565,14 @@ test('Verify token and set up auth only on the fist call, then prepare on prepar stdout: t.context.stdout, stderr: t.context.stderr, logger: t.context.logger, - nextRelease: {version: '1.0.0'}, + nextRelease: {channel: 'next', version: '1.0.0'}, } ); + t.deepEqual(result, {name: 'npm package (@next dist-tag)', url: undefined}); + t.is(await execa.stdout('npm', ['view', pkg.name, 'dist-tags.next'], {cwd, env}), '1.0.0'); + + result = await t.context.m.addChannel({}, {logger: t.context.logger, nextRelease: {version: '1.0.0'}}); + t.deepEqual(result, {name: 'npm package (@latest dist-tag)', url: undefined}); + t.is(await execa.stdout('npm', ['view', pkg.name, 'dist-tags.latest'], {cwd, env}), '1.0.0'); });