Skip to content

Commit

Permalink
feat: support nextRelease.channel property in publish step
Browse files Browse the repository at this point in the history
  • Loading branch information
pvdlg committed Nov 29, 2018
1 parent baf071b commit b8deba7
Show file tree
Hide file tree
Showing 7 changed files with 43 additions and 90 deletions.
3 changes: 3 additions & 0 deletions lib/get-channel.js
@@ -0,0 +1,3 @@
const semver = require('semver');

module.exports = channel => (channel ? (semver.validRange(channel) ? `release-${channel}` : channel) : 'latest');
21 changes: 5 additions & 16 deletions 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,
});
8 changes: 5 additions & 3 deletions 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) => {
Expand All @@ -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,
});
Expand All @@ -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',
Expand Down
3 changes: 2 additions & 1 deletion package.json
Expand Up @@ -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",
Expand Down
15 changes: 15 additions & 0 deletions 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');
});
71 changes: 4 additions & 67 deletions 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',
}
);
});
12 changes: 9 additions & 3 deletions test/integration.test.js
Expand Up @@ -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'},
}
);

Expand Down Expand Up @@ -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,
Expand All @@ -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');
});

0 comments on commit b8deba7

Please sign in to comment.