mirror of https://github.com/embarklabs/embark.git
190 lines
5.6 KiB
JavaScript
190 lines
5.6 KiB
JavaScript
/* global process require */
|
||
|
||
const chalk = require('chalk');
|
||
const {execSync} = require('child_process');
|
||
const minimist = require('minimist');
|
||
const {prompt} = require('promptly');
|
||
const standardVersion = require('standard-version');
|
||
|
||
const args = minimist(process.argv.slice(2));
|
||
|
||
const DEFAULT_UPSTREAM_REPO_BRANCH = 'master';
|
||
const DEFAULT_UPSTREAM_REPO_ORIGIN = 'origin';
|
||
const branch = args['repo-branch'] || DEFAULT_UPSTREAM_REPO_BRANCH;
|
||
const origin = args['repo-origin'] || DEFAULT_UPSTREAM_REPO_ORIGIN;
|
||
|
||
const distTag = args['npm-dist-tag'];
|
||
const dryRun = args['dry-run'];
|
||
const prerelease = args.prerelease;
|
||
const releaseAs = args['release-as'];
|
||
const sign = args.sign;
|
||
|
||
// eslint-disable-next-line no-confusing-arrow
|
||
const dryRunMaybe = () => dryRun ? leftPad1(chalk.yellow('(DRY RUN)')) : '';
|
||
const execSyncInherit = (cmd) => execSync(cmd, {stdio: 'inherit'});
|
||
// eslint-disable-next-line no-confusing-arrow
|
||
const leftPad1 = (str) => ' ' + str;
|
||
// eslint-disable-next-line no-confusing-arrow
|
||
const leftPad1Maybe = (str) => str ? leftPad1(str) : str;
|
||
const log = (mark, str) => console.log(mark, str.filter(s => !!s).join(' '));
|
||
const logError = (...str) => log(chalk.red('✘'), str);
|
||
const logInfo = (...str) => log(chalk.blue('ℹ'), str);
|
||
const logSuccess = (...str) => log(chalk.green('✔'), str);
|
||
const logWarning = (...str) => log(chalk.yellow('‼︎'), str);
|
||
|
||
const yesNoValidator = (input) => {
|
||
const _input = input && input[0].toLowerCase();
|
||
if (!['y', 'n'].includes(_input)) {
|
||
throw new Error(chalk.red('✘') + leftPad1(`Please answer [y]es or [n]o.`));
|
||
}
|
||
return _input;
|
||
};
|
||
|
||
const promptOpts = {default: 'blank', validator: yesNoValidator};
|
||
|
||
const proceedAnywayPrompt = async () => {
|
||
let answer = await prompt(
|
||
`${chalk.yellow('⁉︎')} Proceed anyway? [y/n]`,
|
||
promptOpts
|
||
);
|
||
if (answer === 'n') {
|
||
logWarning(`Stopping right here.`);
|
||
process.exit(0);
|
||
}
|
||
};
|
||
|
||
const dryRunPrompt = async () => {
|
||
let answer = await prompt(
|
||
`${chalk.blue('⁇')} This is ${chalk.yellow('NOT')} a --dry-run.` +
|
||
leftPad1(`Did you complete a successful --dry-run first? [y/n]`),
|
||
promptOpts
|
||
);
|
||
if (answer === 'n') await proceedAnywayPrompt();
|
||
};
|
||
|
||
(async () => {
|
||
try {
|
||
if (!dryRun) await dryRunPrompt();
|
||
|
||
logInfo(`Determining the current branch...`);
|
||
|
||
let currentBranch;
|
||
try {
|
||
currentBranch = execSync(`git rev-parse --abbrev-ref HEAD`)
|
||
.toString()
|
||
.trim();
|
||
} catch (e) {
|
||
logError(`Couldn't determine the branch. Please check the error above.`);
|
||
throw new Error();
|
||
}
|
||
|
||
if (currentBranch !== branch) {
|
||
logError(
|
||
`Current branch '${currentBranch}' is not the same as release branch`,
|
||
`'${branch}'. Please checkout the release branch before rerunning this`,
|
||
`script or rerun with '--repo-branch ${currentBranch}'.`
|
||
);
|
||
throw new Error();
|
||
}
|
||
|
||
logSuccess(`Current branch and release branch are the same.`);
|
||
logInfo(`Checking the working tree...`);
|
||
|
||
try {
|
||
execSyncInherit(`npm run --silent check-working-tree`);
|
||
logSuccess(`Working tree is clean.`);
|
||
} catch (e) {
|
||
logError(
|
||
`Working tree is dirty or has untracked files. Please make necessary`,
|
||
`changes or commits before rerunning this script.`
|
||
);
|
||
throw new Error();
|
||
}
|
||
|
||
logInfo(
|
||
`Fetching from origin '${origin}' to compare local and remote branches...`
|
||
);
|
||
|
||
try {
|
||
execSyncInherit(`git fetch ${origin}`);
|
||
} catch (e) {
|
||
logError(`Couldn't fetch latest commits. Please check the error above.`);
|
||
throw new Error();
|
||
}
|
||
|
||
let localRef, originRef;
|
||
try {
|
||
localRef = execSync(`git rev-parse ${branch}`).toString();
|
||
originRef = execSync(`git rev-parse ${origin}/${branch}`).toString();
|
||
} catch (e) {
|
||
logError(`A problem occured. Please check the error above.`);
|
||
throw new Error();
|
||
}
|
||
|
||
if (localRef !== originRef) {
|
||
logError(
|
||
`Local branch '${branch}' is not in sync with '${origin}/${branch}'.`,
|
||
`Please sync branches before rerunning this script.`
|
||
);
|
||
throw new Error();
|
||
}
|
||
|
||
logSuccess(`Local branch is in sync with remote branch.`);
|
||
logInfo(`Running Standard Version${dryRunMaybe()}...`);
|
||
|
||
await standardVersion({
|
||
dryRun,
|
||
prerelease,
|
||
releaseAs,
|
||
sign
|
||
});
|
||
|
||
logInfo(`Publishing new Embark version on npm${dryRunMaybe()}...`);
|
||
|
||
const npmPublishCommand = [
|
||
`npm publish`,
|
||
leftPad1Maybe(`${distTag ? `--tag ${distTag}` : ''}`),
|
||
leftPad1Maybe(`${dryRun ? '--dry-run' : ''}`)
|
||
].join('');
|
||
|
||
try {
|
||
execSyncInherit(npmPublishCommand);
|
||
logSuccess(`Successfully published latest version${dryRunMaybe()}.`);
|
||
} catch (e) {
|
||
logError(
|
||
`Couldn't publish version on npm${dryRunMaybe()}.`,
|
||
`Please check the error above.`
|
||
);
|
||
throw new Error();
|
||
}
|
||
|
||
logInfo(
|
||
`Pushing release commit and tag to origin '${origin}' on branch`,
|
||
`'${branch}'${dryRunMaybe()}...`
|
||
);
|
||
|
||
const gitPushCommand = [
|
||
`git push --follow-tags ${origin} ${branch}`,
|
||
leftPad1Maybe(`${dryRun ? '--dry-run' : ''}`)
|
||
].join('');
|
||
|
||
try {
|
||
execSyncInherit(gitPushCommand);
|
||
logSuccess(`Successfully pushed${dryRunMaybe()}.`);
|
||
} catch (e) {
|
||
logError(
|
||
`Couldn't push${dryRunMaybe()}. Please check the error above.`
|
||
);
|
||
throw new Error();
|
||
}
|
||
|
||
logSuccess(`Woohoo! Done${dryRunMaybe()}.`);
|
||
} catch (e) {
|
||
logError(
|
||
`Stopping right here${dryRunMaybe()}.`,
|
||
dryRun ? '' : `Make sure to clean up commits and tags as necessary.`
|
||
);
|
||
process.exit(1);
|
||
}
|
||
})();
|