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

Break up release.js #3723

Merged
merged 6 commits into from
Jul 13, 2020
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions .ci/jobs/elastic+eui+npm-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@
npm install -g yarn
yarn

npm run release -- --type=${version_type} --steps=test,build,version,tag

set +x

export VAULT_TOKEN=$(vault write -field=token auth/approle/login role_id="$VAULT_ROLE_ID" secret_id="$VAULT_SECRET_ID")
Expand All @@ -49,5 +51,4 @@

set -x

export VERSION_TYPE=${version_type}
npm run release
npm run release -- --type=${version_type} --steps=publish,docs
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@
"@types/uuid": "^3.4.4",
"@typescript-eslint/eslint-plugin": "^3.2.0",
"@typescript-eslint/parser": "^3.2.0",
"argparse": "^1.0.10",
"autoprefixer": "^7.1.5",
"axe-core": "^3.3.2",
"axe-puppeteer": "^1.0.0",
Expand Down
121 changes: 88 additions & 33 deletions scripts/release.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
const argparse = require('argparse');
const chalk = require('chalk');
const fs = require('fs');
const git = require('nodegit');
const path = require('path');
const prompt = require('prompt');
const { execSync } = require('child_process');
let { execSync } = require('child_process');

const cwd = path.resolve(__dirname, '..');
const stdio = 'inherit';
Expand All @@ -18,6 +19,15 @@ const humanReadableTypes = {
[TYPE_PATCH]: 'patch'
};

const args = parseArguments();

if (args.dry_run) {
console.warn(chalk.yellow('Dry run mode: no changes will be pushed to npm or Github'));
execSync = function() {
console.log.apply(null, arguments);
};
}

(async function () {
// make sure the release script is being run by npm (required for `npm publish` step)
// https://github.com/yarnpkg/yarn/issues/5063
Expand All @@ -31,35 +41,87 @@ const humanReadableTypes = {
await ensureMasterBranch();

// run linting and unit tests
execSync('npm test', execOptions);
if (args.steps.indexOf('test') > -1) {
execSync('npm test', execOptions);
}

// (trans|com)pile `src` into `lib` and `dist`
execSync('npm run build', execOptions);
if (args.steps.indexOf('build') > -1) {
execSync('npm run build', execOptions);
}

// prompt user for what type of version bump to make (major|minor|patch)
const versionTarget = await getVersionTypeFromChangelog();

if (args.steps.indexOf('version') > -1) {
// prompt user for what type of version bump to make (major|minor|patch)
const versionTarget = await getVersionTypeFromChangelog();

// build may have generated a new src-docs/src/i18ntokens.json file, dirtying the git workspace
// it's important to track those changes with this release, so determine the changes and write them
// to src-docs/src/i18ntokens_changelog.json, comitting both to the workspace before running `npm version`
execSync(`npm run update-token-changelog -- ${versionTarget}`, execOptions);
// build may have generated a new src-docs/src/i18ntokens.json file, dirtying the git workspace
// it's important to track those changes with this release, so determine the changes and write them
// to src-docs/src/i18ntokens_changelog.json, comitting both to the workspace before running `npm version`
execSync(`npm run update-token-changelog -- ${versionTarget}`, execOptions);

// update package.json & package-lock.json version, git commit, git tag
execSync(`npm version ${versionTarget}`, execOptions);
// update package.json & package-lock.json version, git commit, git tag
execSync(`npm version ${versionTarget}`, execOptions);
}

// push the version commit & tag to upstream
execSync('git push upstream --tags', execOptions);
if (args.steps.indexOf('tag') > -1) {
// push the version commit & tag to upstream
execSync('git push upstream --tags', execOptions);
}

// prompt user for npm 2FA
const otp = await getOneTimePassword();
if (args.steps.indexOf('publish') > -1) {
// prompt user for npm 2FA
const otp = await getOneTimePassword();

// publish new version to npm
execSync(`npm publish --otp=${otp}`, execOptions);
// publish new version to npm
execSync(`npm publish --otp=${otp}`, execOptions);
}

// update docs, git commit, git push
execSync('npm run sync-docs', execOptions);
if (args.steps.indexOf('docs') > -1) {
// update docs, git commit, git push
execSync('npm run sync-docs', execOptions);
}
}()).catch(e => console.error(e));

function parseArguments() {
const parser = new argparse.ArgumentParser({
addHelp: true,
description: 'Tag and publish a new version of EUI',
});

parser.addArgument('--type', {
help: 'Version type; can be "major", "minor" or "patch"',
choices: Object.values(humanReadableTypes),
});

parser.addArgument('--dry-run', {
action: 'storeTrue',
defaultValue: false,
help: 'Dry run mode; no changes are made',
});

const allSteps = ['test', 'build', 'version', 'tag', 'publish', 'docs'];
parser.addArgument('--steps', {
help: 'Which release steps to run; a comma-separated list of values that can include "test", "build", "version", "tag", "publish" and "docs". If no value is given, all steps are run. Example: --steps=test,build,version,tag',
defaultValue: allSteps.join(','),
});

const args = parser.parseArgs();

// validate --steps argument
const steps = args.steps.trim().split(',');
chandlerprall marked this conversation as resolved.
Show resolved Hide resolved
const diff = steps.filter(x => allSteps.indexOf(x) === -1);
if (diff.length > 0) {
console.error(`Invalid --step value(s): ${diff.join(', ')}`);
process.exit(1);
}

return {
...args,
steps,
};
}

async function ensureMasterBranch() {
// ignore master check in CI since it's checking out the HEAD commit instead
if (process.env.CI === 'true') {
Expand Down Expand Up @@ -131,23 +193,17 @@ async function getVersionTypeFromChangelog() {
console.log('');
console.log(`${chalk.magenta('The recommended version update for these changes is')} ${chalk.blue(humanReadableRecommendation)}`);

// checking for VERSION_TYPE environment variable, which overrides prompts to
// the user to choose a version type; this is used by CI to automate releases
const envVersion = process.env.VERSION_TYPE;
if (envVersion) {
// checking for --type argument value; used by CI to automate releases
const versionType = args.type;
if (versionType) {
// detected version type preference set
console.log(`${chalk.magenta('VERSION_TYPE environment variable identifed, set to')} ${chalk.blue(envVersion)}`);

if (['major', 'minor', 'patch'].indexOf(envVersion) === -1) {
console.error(`${chalk.magenta('VERSION_TYPE environment variable is not "major", "minor" or "patch"')}`);
process.exit(1);
}
console.log(`${chalk.magenta('--type argument identifed, set to')} ${chalk.blue(versionType)}`);

if (envVersion !== recommendedType) {
console.warn(`${chalk.yellow('WARNING: VERSION_TYPE does not match recommended version update')}`);
if (versionType !== humanReadableRecommendation) {
console.warn(`${chalk.yellow('WARNING: --type argument does not match recommended version update')}`);
}

return envVersion;
return versionType;
} else {
console.log(`${chalk.magenta('What part of the package version do you want to bump?')} ${chalk.gray('(major, minor, patch)')}`);

Expand Down Expand Up @@ -189,7 +245,6 @@ async function getOneTimePassword() {
console.log(chalk.magenta('The @elastic organization requires membership and 2FA to publish'));

if (process.env.NPM_OTP) {
// skip prompting user for manual input if NPM_OTP env var is present
console.log(chalk.magenta('2FA code provided by NPM_OTP environment variable'));
return process.env.NPM_OTP;
}
Expand Down
7 changes: 7 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1924,6 +1924,13 @@ are-we-there-yet@~1.1.2:
delegates "^1.0.0"
readable-stream "^2.0.6"

argparse@^1.0.10:
version "1.0.10"
resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911"
integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==
dependencies:
sprintf-js "~1.0.2"

argparse@^1.0.7:
version "1.0.9"
resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.9.tgz#73d83bc263f86e97f8cc4f6bae1b0e90a7d22c86"
Expand Down