Release script follow-up work after 16.1.0-beta release (#11437)
* Build script creates git tag * Build script post instructions print better relative paths * Pre-release (<1.0) version numbers also include pre-release suffix (eg '-beta.0') * Post-NPM-publish step properly handles minor rev comparison check * Release script also updates @next tag when publishing @latest * Fixed a typo. Improved inline comment.
Brian Vaughn committed
Nov 3, 2017 at 13:19 UTC
af08b5cbcaf4d3e3ad965a9165e41688733a7771
5 files changed
+76
-14
scripts/release/build-commands/add-git-tag.js
new
+20
@@ -0,0 +1,20 @@
1
+#!/usr/bin/env node
2
+
3
+'use strict';
4
+
5
+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
+ });
13
+};
14
+
15
+module.exports = async ({cwd, dry, version}) => {
16
+ return logPromise(
17
+ run({cwd, dry, version}),
18
+ `Creating git tag ${chalk.yellow.bold(version)}`
19
+ );
20
+};
scripts/release/build-commands/print-post-build-summary.js
+17
-6
@@ -3,16 +3,27 @@
3
'use strict';
4
5
const chalk = require('chalk');
6
+const {join, relative} = require('path');
7
const {getUnexecutedCommands} = require('../utils');
8
9
const CHANGELOG_PATH =
10
'https://github.com/facebook/react/edit/master/CHANGELOG.md';
11
11
-module.exports = params => {
12
+module.exports = ({cwd, dry, path, version}) => {
13
+ const publishPath = relative(
14
+ process.env.PWD,
15
+ join(__dirname, '../publish.js')
16
+ );
17
const command =
13
- `./publish.js -v ${params.version}` +
14
- (params.path ? ` -p ${params.path}` : '') +
15
- (params.dry ? ' --dry' : '');
18
+ `${publishPath} -v ${version}` +
19
+ (path ? ` -p ${path}` : '') +
20
+ (dry ? ' --dry' : '');
21
+
22
+ const packagingFixturesPath = join(cwd, 'fixtures/packaging');
23
+ const standaloneFixturePath = join(
24
+ cwd,
25
+ 'fixtures/packaging/babel-standalone/dev.html'
26
+ );
27
28
console.log(
29
chalk`
@@ -29,9 +40,9 @@ module.exports = params => {
40
41
{bold.underline Step 2: Smoke test the packages}
42
32
- 1. Open {yellow.bold fixtures/packaging/babel-standalone/dev.html} in the browser.
43
+ 1. Open {yellow.bold ${standaloneFixturePath}} in the browser.
44
2. It should say {italic "Hello world!"}
34
- 3. Next go to {yellow.bold fixtures/packaging} and run {bold node build-all.js}
45
+ 3. Next go to {yellow.bold ${packagingFixturesPath}} and run {bold node build-all.js}
46
4. Install the "serve" module ({bold npm install -g serve})
47
5. Go to the repo root and {bold serve -s .}
48
6. Open {blue.bold http://localhost:5000/fixtures/packaging}
scripts/release/build-commands/update-package-versions.js
+11
-4
@@ -32,11 +32,18 @@ const update = async ({cwd, dry, version}) => {
32
const path = join(cwd, 'packages', project, 'package.json');
33
const json = await readJson(path);
34
35
- // Unstable packages (eg version < 1.0) are treated differently.
36
- // In order to simplify DX for the release engineer,
37
- // These packages are auto-incremented by a minor version number.
35
+ // Unstable packages (eg version < 1.0) are treated specially:
36
+ // Rather than use the release version (eg 16.1.0)-
37
+ // We just auto-increment the minor version (eg 0.1.0 -> 0.2.0).
38
+ // If we're doing a prerelease, we also append the suffix (eg 0.2.0-beta).
39
if (semver.lt(json.version, '1.0.0')) {
39
- json.version = `0.${semver.minor(json.version) + 1}.0`;
40
+ const prerelease = semver.prerelease(version);
41
+ let suffix = '';
42
+ if (prerelease) {
43
+ suffix = `-${prerelease.join('.')}`;
44
+ }
45
+
46
+ json.version = `0.${semver.minor(json.version) + 1}.0${suffix}`;
47
} else {
48
json.version = version;
49
}
scripts/release/build.js
+2
@@ -9,6 +9,7 @@ const run = async () => {
9
const chalk = require('chalk');
10
const logUpdate = require('log-update');
11
12
+ const addGitTag = require('./build-commands/add-git-tag');
13
const buildArtifacts = require('./build-commands/build-artifacts');
14
const checkCircleCiStatus = require('./build-commands/check-circle-ci-status');
15
const checkEnvironmentVariables = require('./build-commands/check-environment-variables');
@@ -39,6 +40,7 @@ const run = async () => {
40
await runAutomatedTests(params);
41
await updatePackageVersions(params);
42
await buildArtifacts(params);
43
+ await addGitTag(params);
44
await printPostBuildSummary(params);
45
} catch (error) {
46
logUpdate.clear();
scripts/release/publish-commands/publish-to-npm.js
+26
-4
@@ -3,6 +3,7 @@
3
'use strict';
4
5
const chalk = require('chalk');
6
+const {readJson} = require('fs-extra');
7
const {join} = require('path');
8
const semver = require('semver');
9
const {execRead, execUnlessDry, logPromise} = require('../utils');
@@ -10,25 +11,46 @@ const {projects} = require('../config');
11
12
const push = async ({cwd, dry, version}) => {
13
const errors = [];
13
- const tag = semver.prerelease(version) ? 'next' : 'latest';
14
+ const isPrerelease = semver.prerelease(version);
15
+ const tag = isPrerelease ? 'next' : 'latest';
16
17
const publishProject = async project => {
18
try {
19
const path = join(cwd, 'build', 'packages', project);
20
await execUnlessDry(`npm publish --tag ${tag}`, {cwd: path, dry});
21
22
+ const packagePath = join(
23
+ cwd,
24
+ 'build',
25
+ 'packages',
26
+ project,
27
+ 'package.json'
28
+ );
29
+ const packageJSON = await readJson(packagePath);
30
+ const packageVersion = packageJSON.version;
31
+
32
if (!dry) {
33
const status = JSON.parse(
34
await execRead(`npm info ${project} dist-tags --json`)
35
);
36
const remoteVersion = status[tag];
37
26
- if (remoteVersion !== version) {
38
+ // Compare remote version to package.json version,
39
+ // To better handle the case of pre-release versions.
40
+ if (remoteVersion !== packageVersion) {
41
throw Error(
28
- chalk`Publised version {yellow.bold ${version}} for ` +
42
+ chalk`Publised version {yellow.bold ${packageVersion}} for ` +
43
`{bold ${project}} but NPM shows {yellow.bold ${remoteVersion}}`
44
);
45
}
46
+
47
+ // If we've just published a stable release,
48
+ // Update the @next tag to also point to it (so @next doens't lag behind).
49
+ if (!isPrerelease) {
50
+ await execUnlessDry(
51
+ `npm dist-tag add ${project}@${packageVersion} next`
52
+ );
53
+ }
54
}
55
} catch (error) {
56
errors.push(error.message);
@@ -48,5 +70,5 @@ const push = async ({cwd, dry, version}) => {
70
};
71
72
module.exports = async params => {
51
- return logPromise(push(params), 'Pushing to git remote');
73
+ return logPromise(push(params), 'Publishing packages to NPM');
74
};