Skip to content

Commit

Permalink
Allow explicit private publish to prevent public publish prompt (#497)
Browse files Browse the repository at this point in the history
Co-authored-by: Itai Steinherz <itaisteinherz@gmail.com>
  • Loading branch information
kylemh and itaisteinherz committed Feb 26, 2020
1 parent 5f52e81 commit 08b52a2
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 28 deletions.
10 changes: 10 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,16 @@ To publish [scoped packages](https://docs.npmjs.com/misc/scope#publishing-public
}
```

### Private Org-scoped packages

To publish a [private Org-scoped package](https://docs.npmjs.com/creating-and-publishing-an-org-scoped-package#publishing-a-private-org-scoped-package), you need to set the access level to `restricted`. You can do that by adding the following to your `package.json`:

```json
"publishConfig": {
"access": "restricted"
}
```

### Publish to a custom registry

Set the [`registry` option](https://docs.npmjs.com/misc/config#registry) in package.json to the URL of your registry:
Expand Down
9 changes: 8 additions & 1 deletion source/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -95,11 +95,18 @@ updateNotifier({pkg: cli.pkg}).notify();
...cli.flags
};

const runPublish = flags.publish && !pkg.private;

const availability = await isPackageNameAvailable(pkg);

const version = cli.input.length > 0 ? cli.input[0] : false;

const options = await ui({...flags, availability, version}, pkg);
const options = await ui({
...flags,
availability,
version,
runPublish
}, pkg);

if (!options.confirm) {
process.exit(0);
Expand Down
14 changes: 3 additions & 11 deletions source/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,6 @@ const exec = (cmd, args) => {

// eslint-disable-next-line default-param-last
module.exports = async (input = 'patch', options) => {
options = {
cleanup: true,
tests: true,
publish: true,
...options
};

if (!hasYarn() && options.yarn) {
throw new Error('Could not use Yarn without yarn.lock file');
}
Expand All @@ -56,7 +49,6 @@ module.exports = async (input = 'patch', options) => {
const pkg = util.readPkg(options.contents);
const runTests = options.tests && !options.yolo;
const runCleanup = options.cleanup && !options.yolo;
const runPublish = options.publish && !pkg.private;
const pkgManager = options.yarn === true ? 'yarn' : 'npm';
const pkgManagerName = options.yarn === true ? 'Yarn' : 'npm';
const rootDir = pkgDir.sync();
Expand Down Expand Up @@ -106,7 +98,7 @@ module.exports = async (input = 'patch', options) => {
const tasks = new Listr([
{
title: 'Prerequisite check',
enabled: () => runPublish,
enabled: () => options.runPublish,
task: () => prerequisiteTasks(input, pkg, options)
},
{
Expand Down Expand Up @@ -194,7 +186,7 @@ module.exports = async (input = 'patch', options) => {
}
]);

if (runPublish) {
if (options.runPublish) {
tasks.add([
{
title: `Publishing package using ${pkgManagerName}`,
Expand Down Expand Up @@ -252,7 +244,7 @@ module.exports = async (input = 'patch', options) => {
return '[Preview] Command not executed: git push --follow-tags.';
}

if (publishStatus === 'FAILED' && runPublish) {
if (publishStatus === 'FAILED' && options.runPublish) {
return 'Couldn\'t publish package to npm; not pushing.';
}
},
Expand Down
11 changes: 5 additions & 6 deletions source/ui.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,8 @@ module.exports = async (options, pkg) => {
const repoUrl = pkg.repository && githubUrlFromGit(pkg.repository.url, {extraBaseUrls});
const pkgManager = options.yarn ? 'yarn' : 'npm';
const registryUrl = await getRegistryUrl(pkgManager, pkg);
const runPublish = options.publish && !pkg.private;

if (runPublish) {
if (options.runPublish) {
checkIgnoreStrategy(pkg);
}

Expand Down Expand Up @@ -106,7 +105,7 @@ module.exports = async (options, pkg) => {
type: 'list',
name: 'tag',
message: 'How should this pre-release version be tagged in npm?',
when: answers => options.publish && !pkg.private && version.isPrereleaseOrIncrement(answers.version) && !options.tag,
when: answers => options.runPublish && version.isPrereleaseOrIncrement(answers.version) && !options.tag,
choices: async () => {
const existingPrereleaseTags = await prereleaseTags(pkg.name);

Expand All @@ -124,7 +123,7 @@ module.exports = async (options, pkg) => {
type: 'input',
name: 'tag',
message: 'Tag',
when: answers => options.publish && !pkg.private && version.isPrereleaseOrIncrement(answers.version) && !options.tag && !answers.tag,
when: answers => options.runPublish && version.isPrereleaseOrIncrement(answers.version) && !options.tag && !answers.tag,
validate: input => {
if (input.length === 0) {
return 'Please specify a tag, for example, `next`.';
Expand All @@ -140,7 +139,7 @@ module.exports = async (options, pkg) => {
{
type: 'confirm',
name: 'publishScoped',
when: isScoped(pkg.name) && !options.availability.isAvailable && !options.availability.isUnknown && options.publish && !pkg.private,
when: isScoped(pkg.name) && !options.availability.isAvailable && !options.availability.isUnknown && options.runPublish && (pkg.publishConfig && pkg.publishConfig.access !== 'restricted'),
message: `This scoped repo ${chalk.bold.magenta(pkg.name)} hasn't been published. Do you want to publish it publicly?`,
default: false
}
Expand Down Expand Up @@ -177,7 +176,7 @@ module.exports = async (options, pkg) => {
const answers = await inquirer.prompt([{
type: 'confirm',
name: 'confirm',
when: isScoped(pkg.name) && options.publish && !pkg.private,
when: isScoped(pkg.name) && options.runPublish,
message: `Failed to check availability of scoped repo name ${chalk.bold.magenta(pkg.name)}. Do you want to try and publish it anyway?`,
default: false
}]);
Expand Down
27 changes: 17 additions & 10 deletions test/index.js
Original file line number Diff line number Diff line change
@@ -1,23 +1,30 @@
import test from 'ava';
import np from '../source';

const defaultOptions = {
cleanup: true,
tests: true,
publish: true,
runPublish: true
};

test('version is invalid', async t => {
const message = 'Version should be either patch, minor, major, prepatch, preminor, premajor, prerelease, or a valid semver version.';
await t.throwsAsync(np('foo'), message);
await t.throwsAsync(np('4.x.3'), message);
await t.throwsAsync(np('foo', defaultOptions), message);
await t.throwsAsync(np('4.x.3', defaultOptions), message);
});

test('version is pre-release', async t => {
const message = 'You must specify a dist-tag using --tag when publishing a pre-release version. This prevents accidentally tagging unstable versions as "latest". https://docs.npmjs.com/cli/dist-tag';
await t.throwsAsync(np('premajor'), message);
await t.throwsAsync(np('preminor'), message);
await t.throwsAsync(np('prepatch'), message);
await t.throwsAsync(np('prerelease'), message);
await t.throwsAsync(np('10.0.0-0'), message);
await t.throwsAsync(np('10.0.0-beta'), message);
await t.throwsAsync(np('premajor', defaultOptions), message);
await t.throwsAsync(np('preminor', defaultOptions), message);
await t.throwsAsync(np('prepatch', defaultOptions), message);
await t.throwsAsync(np('prerelease', defaultOptions), message);
await t.throwsAsync(np('10.0.0-0', defaultOptions), message);
await t.throwsAsync(np('10.0.0-beta', defaultOptions), message);
});

test('errors on too low version', async t => {
await t.throwsAsync(np('1.0.0'), /New version `1\.0\.0` should be higher than current version `\d+\.\d+\.\d+`/);
await t.throwsAsync(np('1.0.0-beta'), /New version `1\.0\.0-beta` should be higher than current version `\d+\.\d+\.\d+`/);
await t.throwsAsync(np('1.0.0', defaultOptions), /New version `1\.0\.0` should be higher than current version `\d+\.\d+\.\d+`/);
await t.throwsAsync(np('1.0.0-beta', defaultOptions), /New version `1\.0\.0-beta` should be higher than current version `\d+\.\d+\.\d+`/);
});

0 comments on commit 08b52a2

Please sign in to comment.