Skip to content

Commit

Permalink
Add --release-draft-only flag (#578)
Browse files Browse the repository at this point in the history
  • Loading branch information
Drarig29 committed Dec 26, 2020
1 parent 3466903 commit 316bed2
Show file tree
Hide file tree
Showing 5 changed files with 107 additions and 37 deletions.
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
60 changes: 52 additions & 8 deletions source/ui.js
Expand Up @@ -11,18 +11,26 @@ 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 has not been published yet.');
}

const log = await git.commitLogFromRevision(revision);

if (!log) {
return {
hasCommits: false,
hasUnreleasedCommits: false,
releaseNotes: () => {}
};
}

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

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

if (!fromLatestTag) {
const latestTag = await git.latestTag();
const versionBumpCommitName = latestTag.slice(1); // Name v1.0.1 becomes 1.0.1
const versionBumpCommitIndex = commits.findIndex(commit => commit.message === versionBumpCommitName);

if (versionBumpCommitIndex > 0) {
commitRangeText = `${revision}...${latestTag}`;
hasUnreleasedCommits = true;
}

// 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,14 +61,15 @@ 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`);

return {
hasCommits: true,
hasUnreleasedCommits,
releaseNotes
};
};
Expand Down Expand Up @@ -92,7 +115,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 +203,24 @@ module.exports = async (options, pkg) => {
}
];

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

if (hasUnreleasedCommits && 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?',
default: false
}]);

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

if (options.version) {
return {
Expand Down

0 comments on commit 316bed2

Please sign in to comment.