Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add --release-draft-only flag #578

Merged
merged 11 commits into from Dec 26, 2020
Merged
27 changes: 14 additions & 13 deletions readme.md
Expand Up @@ -50,19 +50,20 @@ $ np --help
patch | minor | major | prepatch | preminor | premajor | prerelease | 1.2.3

Options
--any-branch Allow publishing from any branch
--branch Name of the release branch (default: master)
--no-cleanup Skips cleanup of node_modules
--no-tests Skips tests
--yolo Skips cleanup and testing
--no-publish Skips publishing
--preview Show tasks without actually executing them
--tag Publish under a given dist-tag
--no-yarn Don't use Yarn
--contents Subdirectory to publish
--no-release-draft Skips opening a GitHub release draft
--test-script Name of npm run script to run tests before publishing (default: test)
--no-2fa Don't enable 2FA on new packages (not recommended)
--any-branch Allow publishing from any branch
--branch Name of the release branch (default: master)
--no-cleanup Skips cleanup of node_modules
--no-tests Skips tests
--yolo Skips cleanup and testing
--no-publish Skips publishing
--preview Show tasks without actually executing them
--tag Publish under a given dist-tag
--no-yarn Don't use Yarn
--contents Subdirectory to publish
--no-release-draft Skips opening a GitHub release draft
--release-draft-only Only opens a GitHub release draft
--test-script Name of npm run script to run tests before publishing (default: test)
--no-2fa Don't enable 2FA on new packages (not recommended)

Examples
$ np
Expand Down
37 changes: 21 additions & 16 deletions source/cli-implementation.js
Expand Up @@ -21,19 +21,20 @@ const cli = meow(`
${version.SEMVER_INCREMENTS.join(' | ')} | 1.2.3

Options
--any-branch Allow publishing from any branch
--branch Name of the release branch (default: master)
--no-cleanup Skips cleanup of node_modules
--no-tests Skips tests
--yolo Skips cleanup and testing
--no-publish Skips publishing
--preview Show tasks without actually executing them
--tag Publish under a given dist-tag
--no-yarn Don't use Yarn
--contents Subdirectory to publish
--no-release-draft Skips opening a GitHub release draft
--test-script Name of npm run script to run tests before publishing (default: test)
--no-2fa Don't enable 2FA on new packages (not recommended)
--any-branch Allow publishing from any branch
--branch Name of the release branch (default: master)
--no-cleanup Skips cleanup of node_modules
--no-tests Skips tests
--yolo Skips cleanup and testing
--no-publish Skips publishing
--preview Show tasks without actually executing them
--tag Publish under a given dist-tag
--no-yarn Don't use Yarn
--contents Subdirectory to publish
--no-release-draft Skips opening a GitHub release draft
--release-draft-only Only opens a GitHub release draft for the latest published version
--test-script Name of npm run script to run tests before publishing (default: test)
--no-2fa Don't enable 2FA on new packages (not recommended)

Examples
$ np
Expand Down Expand Up @@ -65,6 +66,9 @@ const cli = meow(`
releaseDraft: {
type: 'boolean'
},
releaseDraftOnly: {
type: 'boolean'
},
tag: {
type: 'string'
},
Expand Down Expand Up @@ -113,14 +117,15 @@ updateNotifier({pkg: cli.pkg}).notify();
flags['2fa'] = flags['2Fa'];
}

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

const availability = flags.publish ? await isPackageNameAvailable(pkg) : {
isAvailable: false,
isUnknown: false
};

const version = cli.input.length > 0 ? cli.input[0] : false;
// Use current (latest) version when 'releaseDraftOnly', otherwise use the first argument.
const version = flags.releaseDraftOnly ? pkg.version : (cli.input.length > 0 ? cli.input[0] : false);

const options = await ui({
...flags,
Expand All @@ -136,7 +141,7 @@ updateNotifier({pkg: cli.pkg}).notify();
console.log(); // Prints a newline for readability
const newPkg = await np(options.version, options);

if (options.preview) {
if (options.preview || options.releaseDraftOnly) {
return;
}

Expand Down
15 changes: 15 additions & 0 deletions source/git-util.js
Expand Up @@ -29,6 +29,21 @@ const firstCommit = async () => {
return stdout;
};

exports.previousTagOrFirstCommit = async () => {
const {stdout} = await execa('git', ['tag']);
const tags = stdout.split('\n');

if (tags.length === 0) {
return;
}

if (tags.length === 1) {
return firstCommit();
}

return tags[tags.length - 2];
};

exports.latestTagOrFirstCommit = async () => {
let latest;
try {
Expand Down
5 changes: 5 additions & 0 deletions source/index.js
Expand Up @@ -58,6 +58,11 @@ module.exports = async (input = 'patch', options) => {
const testScript = options.testScript || 'test';
const testCommand = options.testScript ? ['run', testScript] : [testScript];

if (options.releaseDraftOnly) {
await releaseTaskHelper(options, pkg);
return pkg;
}

let publishStatus = 'UNKNOWN';
let pushedObjects;

Expand Down
54 changes: 46 additions & 8 deletions source/ui.js
Expand Up @@ -11,9 +11,13 @@ const {prereleaseTags, checkIgnoreStrategy, getRegistryUrl, isExternalRegistry}
const version = require('./version');
const prettyVersionDiff = require('./pretty-version-diff');

const printCommitLog = async (repoUrl, registryUrl) => {
const latest = await git.latestTagOrFirstCommit();
const log = await git.commitLogFromRevision(latest);
const printCommitLog = async (repoUrl, registryUrl, fromLatestTag) => {
const revision = fromLatestTag ? await git.latestTagOrFirstCommit() : await git.previousTagOrFirstCommit();
if (!revision) {
throw new Error('The package hasn\'t been published yet.');
Drarig29 marked this conversation as resolved.
Show resolved Hide resolved
}

const log = await git.commitLogFromRevision(revision);

if (!log) {
return {
Expand All @@ -22,7 +26,9 @@ const printCommitLog = async (repoUrl, registryUrl) => {
};
}

const commits = log.split('\n')
let commitRangeText = `${revision}...master`;

let commits = log.split('\n')
.map(commit => {
const splitIndex = commit.lastIndexOf(' ');
return {
Expand All @@ -31,6 +37,17 @@ const printCommitLog = async (repoUrl, registryUrl) => {
};
});

if (!fromLatestTag) {
const latestTag = await git.latestTag();
commitRangeText = `${revision}...${latestTag}`;

const versionBumpCommitName = latestTag.slice(1); // Name v1.0.1 becomes 1.0.1
const versionBumpCommitIndex = commits.findIndex(commit => commit.message === versionBumpCommitName);

// Get rid of unreleased commits and of the version bump commit.
commits = commits.slice(versionBumpCommitIndex + 1);
}

const history = commits.map(commit => {
const commitMessage = util.linkifyIssues(repoUrl, commit.message);
const commitId = util.linkifyCommit(repoUrl, commit.id);
Expand All @@ -39,9 +56,9 @@ const printCommitLog = async (repoUrl, registryUrl) => {

const releaseNotes = nextTag => commits.map(commit =>
`- ${htmlEscape(commit.message)} ${commit.id}`
).join('\n') + `\n\n${repoUrl}/compare/${latest}...${nextTag}`;
).join('\n') + `\n\n${repoUrl}/compare/${revision}...${nextTag}`;

const commitRange = util.linkifyCommitRange(repoUrl, `${latest}...master`);
const commitRange = util.linkifyCommitRange(repoUrl, commitRangeText);

console.log(`${chalk.bold('Commits:')}\n${history}\n\n${chalk.bold('Commit Range:')}\n${commitRange}\n\n${chalk.bold('Registry:')}\n${registryUrl}\n`);

Expand Down Expand Up @@ -92,7 +109,11 @@ module.exports = async (options, pkg) => {
}
}

console.log(`\nPublish a new version of ${chalk.bold.magenta(pkg.name)} ${chalk.dim(`(current: ${oldVersion})`)}\n`);
if (options.releaseDraftOnly) {
console.log(`\nCreate a release draft on GitHub for ${chalk.bold.magenta(pkg.name)} ${chalk.dim(`(current: ${oldVersion})`)}\n`);
} else {
console.log(`\nPublish a new version of ${chalk.bold.magenta(pkg.name)} ${chalk.dim(`(current: ${oldVersion})`)}\n`);
}

const prompts = [
{
Expand Down Expand Up @@ -176,7 +197,24 @@ module.exports = async (options, pkg) => {
}
];

const {hasCommits, releaseNotes} = await printCommitLog(repoUrl, registryUrl);
const useLatestTag = !options.releaseDraftOnly;
const {hasCommits, releaseNotes} = await printCommitLog(repoUrl, registryUrl, useLatestTag);

if (hasCommits && options.releaseDraftOnly) {
const answers = await inquirer.prompt([{
type: 'confirm',
name: 'confirm',
message: 'Unreleased commits found. They won\'t be included in the release draft, continue?',
Drarig29 marked this conversation as resolved.
Show resolved Hide resolved
default: false
}]);

if (!answers.confirm) {
return {
...options,
...answers
};
}
}

if (options.version) {
return {
Expand Down