@samitouri / QOS-React / commits / ac0e670545

Release script tweaks (#11504)

* Added missing params object to execUnlessDry call * Public package names are no longer hard-coded * Added "v" prefix to git tag * Show more accurate in-progress duration * Properly bucket-bridage params * Prettier * Publish command logs stack with error

Brian Vaughn committed Nov 9, 2017 at 16:29 UTC ac0e670545bb85770c71154e93ef17dc6c08e8a4
11 files changed +50 -40
scripts/release/build-commands/add-git-tag.js
+8 -5
@@ -6,15 +6,18 @@ const chalk = require('chalk');
6 const {execUnlessDry, logPromise} = require('../utils');
7
8 const run = async ({cwd, dry, version}) => {
9 - await execUnlessDry(`git tag -a ${version} -m "Tagging ${version} release"`, {
10 - cwd,
11 - dry,
12 - });
9 + await execUnlessDry(
10 + `git tag -a v${version} -m "Tagging ${version} release"`,
11 + {
12 + cwd,
13 + dry,
14 + }
15 + );
16 };
17
18 module.exports = async ({cwd, dry, version}) => {
19 return logPromise(
20 run({cwd, dry, version}),
18 - `Creating git tag ${chalk.yellow.bold(version)}`
21 + `Creating git tag ${chalk.yellow.bold(`v${version}`)}`
22 );
23 };
scripts/release/build-commands/build-artifacts.js
+1 -1
@@ -28,5 +28,5 @@ const run = async ({cwd, dry, version}) => {
28 };
29
30 module.exports = async params => {
31 - return logPromise(run(params), 'Building artifacts');
31 + return logPromise(run(params), 'Building artifacts', true);
32 };
scripts/release/build-commands/check-npm-permissions.js
+2 -3
@@ -4,9 +4,8 @@
4
5 const chalk = require('chalk');
6 const {execRead, logPromise} = require('../utils');
7 -const {projects} = require('../config');
7
9 -module.exports = async () => {
8 +module.exports = async ({packages}) => {
9 const currentUser = await execRead('npm whoami');
10 const failedProjects = [];
11
@@ -22,7 +21,7 @@ module.exports = async () => {
21 };
22
23 await logPromise(
25 - Promise.all(projects.map(checkProject)),
24 + Promise.all(packages.map(checkProject)),
25 `Checking ${chalk.yellow.bold(currentUser)}'s NPM permissions`
26 );
27
scripts/release/build-commands/check-package-dependencies.js
+6 -6
@@ -5,15 +5,15 @@
5 const chalk = require('chalk');
6 const {readJson} = require('fs-extra');
7 const {join} = require('path');
8 -const {dependencies, projects} = require('../config');
8 +const {dependencies} = require('../config');
9 const {logPromise} = require('../utils');
10
11 -const check = async ({cwd}) => {
11 +const check = async ({cwd, packages}) => {
12 const rootPackage = await readJson(join(cwd, 'package.json'));
13
14 const projectPackages = [];
15 - for (let i = 0; i < projects.length; i++) {
16 - const project = projects[i];
15 + for (let i = 0; i < packages.length; i++) {
16 + const project = packages[i];
17 projectPackages.push(
18 await readJson(join(cwd, join('packages', project), 'package.json'))
19 );
@@ -52,6 +52,6 @@ const check = async ({cwd}) => {
52 }
53 };
54
55 -module.exports = async ({cwd}) => {
56 - return logPromise(check({cwd}), 'Checking runtime dependencies');
55 +module.exports = async params => {
56 + return logPromise(check(params), 'Checking runtime dependencies');
57 };
scripts/release/build-commands/run-automated-tests.js
+2 -1
@@ -28,6 +28,7 @@ module.exports = async ({cwd}) => {
28 );
29 await logPromise(
30 runYarnTask(cwd, 'jest', 'Jest failed'),
31 - 'Running Jest tests'
31 + 'Running Jest tests',
32 + true
33 );
34 };
scripts/release/build-commands/update-package-versions.js
+2 -3
@@ -8,10 +8,9 @@ const {readFileSync, writeFileSync} = require('fs');
8 const {readJson, writeJson} = require('fs-extra');
9 const {join} = require('path');
10 const semver = require('semver');
11 -const {projects} = require('../config');
11 const {execUnlessDry, logPromise} = require('../utils');
12
14 -const update = async ({cwd, dry, version}) => {
13 +const update = async ({cwd, dry, packages, version}) => {
14 try {
15 // Update root package.json
16 const packagePath = join(cwd, 'package.json');
@@ -60,7 +59,7 @@ const update = async ({cwd, dry, version}) => {
59
60 await writeJson(path, json, {spaces: 2});
61 };
63 - await Promise.all(projects.map(updateProjectPackage));
62 + await Promise.all(packages.map(updateProjectPackage));
63
64 // Version sanity check
65 await exec('yarn version-check', {cwd});
scripts/release/build.js
+2
@@ -8,6 +8,7 @@ const {exec} = require('child_process');
8 const run = async () => {
9 const chalk = require('chalk');
10 const logUpdate = require('log-update');
11 + const {getPublicPackages} = require('./utils');
12
13 const addGitTag = require('./build-commands/add-git-tag');
14 const buildArtifacts = require('./build-commands/build-artifacts');
@@ -27,6 +28,7 @@ const run = async () => {
28
29 try {
30 const params = parseBuildParameters();
31 + params.packages = getPublicPackages();
32
33 await checkEnvironmentVariables(params);
34 await validateVersion(params);
scripts/release/config.js
-11
@@ -2,16 +2,6 @@
2
3 const dependencies = ['fbjs', 'object-assign', 'prop-types'];
4
5 -// TODO: enumerate all non-private package folders in packages/*?
6 -const projects = [
7 - 'react',
8 - 'react-art',
9 - 'react-call-return',
10 - 'react-dom',
11 - 'react-reconciler',
12 - 'react-test-renderer',
13 -];
14 -
5 const paramDefinitions = [
6 {
7 name: 'dry',
@@ -38,5 +28,4 @@ const paramDefinitions = [
28 module.exports = {
29 dependencies,
30 paramDefinitions,
41 - projects,
31 };
scripts/release/publish-commands/publish-to-npm.js
+4 -5
@@ -7,9 +7,8 @@ const {readJson} = require('fs-extra');
7 const {join} = require('path');
8 const semver = require('semver');
9 const {execRead, execUnlessDry, logPromise} = require('../utils');
10 -const {projects} = require('../config');
10
12 -const push = async ({cwd, dry, version}) => {
11 +const push = async ({cwd, dry, packages, version}) => {
12 const errors = [];
13 const isPrerelease = semver.prerelease(version);
14 const tag = isPrerelease ? 'next' : 'latest';
@@ -60,18 +59,18 @@ const push = async ({cwd, dry, version}) => {
59 }
60 }
61 } catch (error) {
63 - errors.push(error.message);
62 + errors.push(error.stack);
63 }
64 };
65
67 - await Promise.all(projects.map(publishProject));
66 + await Promise.all(packages.map(publishProject));
67
68 if (errors.length > 0) {
69 throw Error(
70 chalk`
71 Failure publishing to NPM
72
74 - {white ${errors.join('\n')}}`
73 + {white ${errors.join('\n\n')}}`
74 );
75 }
76 };
scripts/release/publish.js
+2
@@ -4,6 +4,7 @@
4
5 const chalk = require('chalk');
6 const logUpdate = require('log-update');
7 +const {getPublicPackages} = require('./utils');
8
9 const checkBuildStatus = require('./publish-commands/check-build-status');
10 const commitChangelog = require('./publish-commands/commit-changelog');
@@ -15,6 +16,7 @@ const publishToNpm = require('./publish-commands/publish-to-npm');
16 // Follows the steps outlined in github.com/facebook/react/issues/10620
17 const run = async () => {
18 const params = parsePublishParams();
19 + params.packages = getPublicPackages();
20
21 try {
22 await checkBuildStatus(params);
scripts/release/utils.js
+21 -5
@@ -3,7 +3,9 @@
3 const chalk = require('chalk');
4 const {dots} = require('cli-spinners');
5 const {exec} = require('child-process-promise');
6 +const {readdirSync, readFileSync} = require('fs');
7 const logUpdate = require('log-update');
8 +const {join} = require('path');
9
10 const execRead = async (command, options) => {
11 const {stdout} = await exec(command, options);
@@ -21,6 +23,17 @@ const execUnlessDry = async (command, {cwd, dry}) => {
23 }
24 };
25
26 +const getPublicPackages = () => {
27 + const packagesRoot = join(__dirname, '..', '..', 'packages');
28 +
29 + return readdirSync(packagesRoot).filter(dir => {
30 + const packagePath = join(packagesRoot, dir, 'package.json');
31 + const packageJSON = JSON.parse(readFileSync(packagePath));
32 +
33 + return packageJSON.private !== true;
34 + });
35 +};
36 +
37 const getUnexecutedCommands = () => {
38 if (unexecutedCommands.length > 0) {
39 return chalk`
@@ -32,17 +45,19 @@ const getUnexecutedCommands = () => {
45 }
46 };
47
35 -const logPromise = async (promise, text, completedLabel = '') => {
48 +const logPromise = async (promise, text, isLongRunningTask = false) => {
49 const {frames, interval} = dots;
50
51 let index = 0;
52
53 + const inProgressMessage = `- this may take a few ${
54 + isLongRunningTask ? 'minutes' : 'seconds'
55 + }`;
56 +
57 const id = setInterval(() => {
58 index = ++index % frames.length;
59 logUpdate(
43 - `${chalk.yellow(frames[index])} ${text} ${chalk.gray(
44 - '- this may take a few seconds'
45 - )}`
60 + `${chalk.yellow(frames[index])} ${text} ${chalk.gray(inProgressMessage)}`
61 );
62 }, interval);
63
@@ -51,7 +66,7 @@ const logPromise = async (promise, text, completedLabel = '') => {
66
67 clearInterval(id);
68
54 - logUpdate(`${chalk.green('✓')} ${text} ${chalk.gray(completedLabel)}`);
69 + logUpdate(`${chalk.green('✓')} ${text}`);
70 logUpdate.done();
71
72 return returnValue;
@@ -65,6 +80,7 @@ const logPromise = async (promise, text, completedLabel = '') => {
80 module.exports = {
81 execRead,
82 execUnlessDry,
83 + getPublicPackages,
84 getUnexecutedCommands,
85 logPromise,
86 };