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

Release script tweaks #11504

Merged
merged 7 commits into from
Nov 9, 2017
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
13 changes: 8 additions & 5 deletions scripts/release/build-commands/add-git-tag.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,18 @@ const chalk = require('chalk');
const {execUnlessDry, logPromise} = require('../utils');

const run = async ({cwd, dry, version}) => {
await execUnlessDry(`git tag -a ${version} -m "Tagging ${version} release"`, {
cwd,
dry,
});
await execUnlessDry(
`git tag -a v${version} -m "Tagging ${version} release"`,
{
cwd,
dry,
}
);
};

module.exports = async ({cwd, dry, version}) => {
return logPromise(
run({cwd, dry, version}),
`Creating git tag ${chalk.yellow.bold(version)}`
`Creating git tag ${chalk.yellow.bold(`v${version}`)}`
);
};
2 changes: 1 addition & 1 deletion scripts/release/build-commands/build-artifacts.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,5 @@ const run = async ({cwd, dry, version}) => {
};

module.exports = async params => {
return logPromise(run(params), 'Building artifacts');
return logPromise(run(params), 'Building artifacts', true);
};
5 changes: 2 additions & 3 deletions scripts/release/build-commands/check-npm-permissions.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,8 @@

const chalk = require('chalk');
const {execRead, logPromise} = require('../utils');
const {projects} = require('../config');

module.exports = async () => {
module.exports = async ({packages}) => {
const currentUser = await execRead('npm whoami');
const failedProjects = [];

Expand All @@ -22,7 +21,7 @@ module.exports = async () => {
};

await logPromise(
Promise.all(projects.map(checkProject)),
Promise.all(packages.map(checkProject)),
`Checking ${chalk.yellow.bold(currentUser)}'s NPM permissions`
);

Expand Down
12 changes: 6 additions & 6 deletions scripts/release/build-commands/check-package-dependencies.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@
const chalk = require('chalk');
const {readJson} = require('fs-extra');
const {join} = require('path');
const {dependencies, projects} = require('../config');
const {dependencies} = require('../config');
const {logPromise} = require('../utils');

const check = async ({cwd}) => {
const check = async ({cwd, packages}) => {
const rootPackage = await readJson(join(cwd, 'package.json'));

const projectPackages = [];
for (let i = 0; i < projects.length; i++) {
const project = projects[i];
for (let i = 0; i < packages.length; i++) {
const project = packages[i];
projectPackages.push(
await readJson(join(cwd, join('packages', project), 'package.json'))
);
Expand Down Expand Up @@ -52,6 +52,6 @@ const check = async ({cwd}) => {
}
};

module.exports = async ({cwd}) => {
return logPromise(check({cwd}), 'Checking runtime dependencies');
module.exports = async params => {
return logPromise(check(params), 'Checking runtime dependencies');
};
3 changes: 2 additions & 1 deletion scripts/release/build-commands/run-automated-tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ module.exports = async ({cwd}) => {
);
await logPromise(
runYarnTask(cwd, 'jest', 'Jest failed'),
'Running Jest tests'
'Running Jest tests',
true
);
};
5 changes: 2 additions & 3 deletions scripts/release/build-commands/update-package-versions.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,9 @@ const {readFileSync, writeFileSync} = require('fs');
const {readJson, writeJson} = require('fs-extra');
const {join} = require('path');
const semver = require('semver');
const {projects} = require('../config');
const {execUnlessDry, logPromise} = require('../utils');

const update = async ({cwd, dry, version}) => {
const update = async ({cwd, dry, packages, version}) => {
try {
// Update root package.json
const packagePath = join(cwd, 'package.json');
Expand Down Expand Up @@ -60,7 +59,7 @@ const update = async ({cwd, dry, version}) => {

await writeJson(path, json, {spaces: 2});
};
await Promise.all(projects.map(updateProjectPackage));
await Promise.all(packages.map(updateProjectPackage));

// Version sanity check
await exec('yarn version-check', {cwd});
Expand Down
2 changes: 2 additions & 0 deletions scripts/release/build.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ const {exec} = require('child_process');
const run = async () => {
const chalk = require('chalk');
const logUpdate = require('log-update');
const {getPublicPackages} = require('./utils');

const addGitTag = require('./build-commands/add-git-tag');
const buildArtifacts = require('./build-commands/build-artifacts');
Expand All @@ -27,6 +28,7 @@ const run = async () => {

try {
const params = parseBuildParameters();
params.packages = getPublicPackages();

await checkEnvironmentVariables(params);
await validateVersion(params);
Expand Down
11 changes: 0 additions & 11 deletions scripts/release/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,6 @@

const dependencies = ['fbjs', 'object-assign', 'prop-types'];

// TODO: enumerate all non-private package folders in packages/*?
const projects = [
'react',
'react-art',
'react-call-return',
'react-dom',
'react-reconciler',
'react-test-renderer',
];

const paramDefinitions = [
{
name: 'dry',
Expand All @@ -38,5 +28,4 @@ const paramDefinitions = [
module.exports = {
dependencies,
paramDefinitions,
projects,
};
12 changes: 6 additions & 6 deletions scripts/release/publish-commands/publish-to-npm.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,8 @@ const {readJson} = require('fs-extra');
const {join} = require('path');
const semver = require('semver');
const {execRead, execUnlessDry, logPromise} = require('../utils');
const {projects} = require('../config');

const push = async ({cwd, dry, version}) => {
const push = async ({cwd, dry, packages, version}) => {
const errors = [];
const isPrerelease = semver.prerelease(version);
const tag = isPrerelease ? 'next' : 'latest';
Expand Down Expand Up @@ -54,23 +53,24 @@ const push = async ({cwd, dry, version}) => {
// Update the @next tag to also point to it (so @next doens't lag behind).
if (!isPrerelease) {
await execUnlessDry(
`npm dist-tag add ${project}@${packageVersion} next`
`npm dist-tag add ${project}@${packageVersion} next`,
{cwd: path, dry}
);
}
}
} catch (error) {
errors.push(error.message);
errors.push(error.stack);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe keep both? We can just collect error instances and then toString() them, no?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Node error.stack includes the message, so it's not needed

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh kay

}
};

await Promise.all(projects.map(publishProject));
await Promise.all(packages.map(publishProject));

if (errors.length > 0) {
throw Error(
chalk`
Failure publishing to NPM

{white ${errors.join('\n')}}`
{white ${errors.join('\n\n')}}`
);
}
};
Expand Down
2 changes: 2 additions & 0 deletions scripts/release/publish.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

const chalk = require('chalk');
const logUpdate = require('log-update');
const {getPublicPackages} = require('./utils');

const checkBuildStatus = require('./publish-commands/check-build-status');
const commitChangelog = require('./publish-commands/commit-changelog');
Expand All @@ -15,6 +16,7 @@ const publishToNpm = require('./publish-commands/publish-to-npm');
// Follows the steps outlined in github.com/facebook/react/issues/10620
const run = async () => {
const params = parsePublishParams();
params.packages = getPublicPackages();

try {
await checkBuildStatus(params);
Expand Down
26 changes: 21 additions & 5 deletions scripts/release/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
const chalk = require('chalk');
const {dots} = require('cli-spinners');
const {exec} = require('child-process-promise');
const {readdirSync, readFileSync} = require('fs');
const logUpdate = require('log-update');
const {join} = require('path');

const execRead = async (command, options) => {
const {stdout} = await exec(command, options);
Expand All @@ -21,6 +23,17 @@ const execUnlessDry = async (command, {cwd, dry}) => {
}
};

const getPublicPackages = () => {
const packagesRoot = join(__dirname, '..', '..', 'packages');

return readdirSync(packagesRoot).filter(dir => {
const packagePath = join(packagesRoot, dir, 'package.json');
const packageJSON = JSON.parse(readFileSync(packagePath));

return packageJSON.private !== true;
});
};

const getUnexecutedCommands = () => {
if (unexecutedCommands.length > 0) {
return chalk`
Expand All @@ -32,17 +45,19 @@ const getUnexecutedCommands = () => {
}
};

const logPromise = async (promise, text, completedLabel = '') => {
const logPromise = async (promise, text, isLongRunningTask = false) => {
const {frames, interval} = dots;

let index = 0;

const inProgressMessage = `- this may take a few ${
isLongRunningTask ? 'minutes' : 'seconds'
}`;

const id = setInterval(() => {
index = ++index % frames.length;
logUpdate(
`${chalk.yellow(frames[index])} ${text} ${chalk.gray(
'- this may take a few seconds'
)}`
`${chalk.yellow(frames[index])} ${text} ${chalk.gray(inProgressMessage)}`
);
}, interval);

Expand All @@ -51,7 +66,7 @@ const logPromise = async (promise, text, completedLabel = '') => {

clearInterval(id);

logUpdate(`${chalk.green('✓')} ${text} ${chalk.gray(completedLabel)}`);
logUpdate(`${chalk.green('✓')} ${text}`);
logUpdate.done();

return returnValue;
Expand All @@ -65,6 +80,7 @@ const logPromise = async (promise, text, completedLabel = '') => {
module.exports = {
execRead,
execUnlessDry,
getPublicPackages,
getUnexecutedCommands,
logPromise,
};