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

Make commit log relative to release branch #580

Merged
merged 8 commits into from
Dec 31, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 4 additions & 1 deletion source/cli-implementation.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const meow = require('meow');
const updateNotifier = require('update-notifier');
const hasYarn = require('has-yarn');
const config = require('./config');
const git = require('./git-util');
const {isPackageNameAvailable} = require('./npm/util');
const version = require('./version');
const util = require('./util');
Expand Down Expand Up @@ -127,11 +128,13 @@ updateNotifier({pkg: cli.pkg}).notify();
// 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 branch = flags.branch || await git.defaultBranch();
const options = await ui({
...flags,
availability,
version,
runPublish
runPublish,
branch
}, pkg);

if (!options.confirm) {
Expand Down
32 changes: 29 additions & 3 deletions source/git-util.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,10 +74,9 @@ exports.currentBranch = async () => {
};

exports.verifyCurrentBranchIsReleaseBranch = async releaseBranch => {
const allowedBranches = releaseBranch ? [releaseBranch] : ['main', 'master'];
const currentBranch = await exports.currentBranch();
if (!allowedBranches.includes(currentBranch)) {
throw new Error(`Not on ${allowedBranches.map(branch => `\`${branch}\``).join('/')} branch. Use --any-branch to publish anyway, or set a different release branch using --branch.`);
if (currentBranch !== releaseBranch) {
throw new Error(`Not on \`${releaseBranch}\` branch. Use --any-branch to publish anyway, or set a different release branch using --branch.`);
}
};

Expand Down Expand Up @@ -152,6 +151,33 @@ exports.tagExistsOnRemote = async tagName => {
}
};

async function hasLocalBranch(branch) {
try {
await execa('git', [
'show-ref',
'--verify',
'--quiet',
`refs/heads/${branch}`
]);
return true;
} catch {
return false;
}
samouri marked this conversation as resolved.
Show resolved Hide resolved
}

exports.defaultBranch = async () => {
for (const branch of ['main', 'master', 'gh-pages']) {
// eslint-disable-next-line no-await-in-loop
if (await hasLocalBranch(branch)) {
return branch;
}
}

throw new Error(
'Could not infer the default Git branch. Please specify one with the --branch flag or with a np config.'
);
};

exports.verifyTagDoesNotExistOnRemote = async tagName => {
if (await exports.tagExistsOnRemote(tagName)) {
throw new Error(`Git tag \`${tagName}\` already exists.`);
Expand Down
8 changes: 4 additions & 4 deletions source/ui.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const {prereleaseTags, checkIgnoreStrategy, getRegistryUrl, isExternalRegistry}
const version = require('./version');
const prettyVersionDiff = require('./pretty-version-diff');

const printCommitLog = async (repoUrl, registryUrl, fromLatestTag) => {
const printCommitLog = async (repoUrl, registryUrl, fromLatestTag, releaseBranch) => {
const revision = fromLatestTag ? await git.latestTagOrFirstCommit() : await git.previousTagOrFirstCommit();
if (!revision) {
throw new Error('The package has not been published yet.');
Expand All @@ -28,7 +28,7 @@ const printCommitLog = async (repoUrl, registryUrl, fromLatestTag) => {
}

let hasUnreleasedCommits = false;
let commitRangeText = `${revision}...master`;
let commitRangeText = `${revision}...${releaseBranch}`;

let commits = log.split('\n')
.map(commit => {
Expand Down Expand Up @@ -64,7 +64,6 @@ const printCommitLog = async (repoUrl, registryUrl, fromLatestTag) => {
).join('\n') + `\n\n${repoUrl}/compare/${revision}...${nextTag}`;

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 {
Expand Down Expand Up @@ -102,6 +101,7 @@ 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 releaseBranch = options.branch;

if (options.runPublish) {
checkIgnoreStrategy(pkg);
Expand Down Expand Up @@ -204,7 +204,7 @@ module.exports = async (options, pkg) => {
];

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

if (hasUnreleasedCommits && options.releaseDraftOnly) {
const answers = await inquirer.prompt([{
Expand Down
12 changes: 6 additions & 6 deletions test/git-tasks.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,16 @@ test.beforeEach(() => {
execaStub.resetStub();
});

test.serial('should fail when release branch is not specified, current branch is not main/master and publishing from any branch not permitted', async t => {
test.serial('should fail when release branch is not specified, current branch is not the release branch, and publishing from any branch not permitted', async t => {
execaStub.createStub([
{
command: 'git symbolic-ref --short HEAD',
exitCode: 0,
stdout: 'feature'
}
]);
await t.throwsAsync(run(testedModule({})),
{message: 'Not on `main`/`master` branch. Use --any-branch to publish anyway, or set a different release branch using --branch.'});
await t.throwsAsync(run(testedModule({branch: 'master'})),
{message: 'Not on `master` branch. Use --any-branch to publish anyway, or set a different release branch using --branch.'});
t.true(SilentRenderer.tasks.some(task => task.title === 'Check current branch' && task.hasFailed()));
});

Expand Down Expand Up @@ -85,7 +85,7 @@ test.serial('should fail when local working tree modified', async t => {
stdout: 'M source/git-tasks.js'
}
]);
await t.throwsAsync(run(testedModule({})), {message: 'Unclean working tree. Commit or stash changes first.'});
await t.throwsAsync(run(testedModule({branch: 'master'})), {message: 'Unclean working tree. Commit or stash changes first.'});
t.true(SilentRenderer.tasks.some(task => task.title === 'Check local working tree' && task.hasFailed()));
});

Expand All @@ -107,7 +107,7 @@ test.serial('should fail when remote history differs', async t => {
stdout: '1'
}
]);
await t.throwsAsync(run(testedModule({})), {message: 'Remote history differs. Please pull changes.'});
await t.throwsAsync(run(testedModule({branch: 'master'})), {message: 'Remote history differs. Please pull changes.'});
t.true(SilentRenderer.tasks.some(task => task.title === 'Check remote history' && task.hasFailed()));
});

Expand All @@ -129,5 +129,5 @@ test.serial('checks should pass when publishing from master, working tree is cle
stdout: ''
}
]);
await t.notThrowsAsync(run(testedModule({})));
await t.notThrowsAsync(run(testedModule({branch: 'master'})));
});