139 lines
3.9 KiB
JavaScript

/**
* Code-freeze helper script.
* Required to be run on a release branch.
*
* It takes extends the committed changes with a new version and release date, runs builds and tests and pushes the
* changes to the release branch.
*/
import yargs from 'yargs';
import { hideBin } from 'yargs/helpers';
import inquirer from 'inquirer';
import semver from 'semver';
import {
cleanNodeModules,
scheduleRelease,
spawnProcess,
displayErrorMessage,
displaySeparator,
} from './utils/index.mjs';
const argv = yargs(hideBin(process.argv))
.boolean('commit')
.default('commit', false)
.describe('commit', '`true` if the state of the repo should be committed automatically at the end of the freeze' +
' process.')
.boolean('push')
.default('push', false)
.describe('push', '`true` if the state of the repo should be pushed to remote automatically at the end of the' +
' freeze process.')
.argv;
const [version, releaseDate] = argv._;
displaySeparator();
(async() => {
// Initial verification prompt
const answers = await inquirer.prompt([
{
type: 'confirm',
name: 'continueFreeze',
message: 'This script will create and commit a code-freeze of the entire repo. \nContinue?',
default: true,
}
]);
if (!answers.continueFreeze) {
process.exit(0);
}
// Check if we're using the minimum required npm version.
{
const processInfo = await spawnProcess('npm --version', { silent: true });
const npmVersion = processInfo.stdout.toString();
if (!semver.satisfies(npmVersion, '>=7.17.0')) {
displayErrorMessage('The minimum required npm version is 7.17.0');
process.exit(1);
}
}
// Check if we're on a release branch.
{
const processInfo = await spawnProcess('git rev-parse --abbrev-ref HEAD', { silent: true });
const branchName = processInfo.stdout.toString();
if (!branchName.startsWith('release/')) {
displayErrorMessage(
'You are not on a release branch. Create a release branch using the `git flow release start`' +
' command on the current `develop` branch.');
process.exit(1);
}
}
// Check if `git flow` is installed.
try {
await spawnProcess('git flow version', { silent: true });
} catch (error) {
displayErrorMessage('Git flow not installed.');
process.exit(1);
}
// Check if all the files are committed.
{
const processInfo = await spawnProcess('git status -s', { silent: true });
const output = processInfo.stdout.toString();
// If there are any uncommitted changes, kill the script.
if (output.length > 0) {
displayErrorMessage('There are uncommitted changes present. Exiting.');
process.exit(1);
}
}
// Bump the version in all packages.
const { version: finalVersion } = await scheduleRelease(version, releaseDate);
// Clear the projects' node_modules nad lock files.
cleanNodeModules();
// Install fresh dependencies
await spawnProcess('npm i --no-audit');
// Clear old package builds.
await spawnProcess('npm run all clean -- --e examples');
// Build all packages (except examples).
await spawnProcess('npm run all build -- --e examples');
// Install the "next" package for examples
await spawnProcess('npm run examples:install next');
// Build the examples directory.
await spawnProcess('npm run in examples build');
// Test all packages.
await spawnProcess('npm run all test');
// Verify if the bundles have the same (and correct) version.
await spawnProcess('node ./scripts/verify-bundles.mjs');
// Generate the CHANGELOG.md file.
await spawnProcess('npm run changelog consume', { stdin: 'pipe' });
if (argv.commit === true) {
// Commit the changes to the release branch.
await spawnProcess('git add .');
await spawnProcess(`git commit -m "${finalVersion}"`);
}
if (argv.push === true) {
// Push the changes to remote.
await spawnProcess(`git flow release publish ${finalVersion}`);
}
})();