Skip to content

Commit 3203821

Browse files
author
Brian Vaughn
committed
Remove --build flag from release scripts
Also update instructions to match recent script changes. Also add reproducible commit SHA to post download instructions to support publishing the Firefox DevTools extension.
1 parent 0e526bc commit 3203821

File tree

9 files changed

+77
-84
lines changed

9 files changed

+77
-84
lines changed

scripts/release/README.md

Lines changed: 8 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -30,35 +30,27 @@ The sections below include meaningful `--tags` in the instructions. However, kee
3030

3131
To prepare a build for a particular commit:
3232
1. Choose a commit from [the commit log](https://github.com/facebook/react/commits/master).
33-
2. Click the "“✓" icon and click the Circle CI "Details" link.
34-
3. Select the `process_artifacts ` job (**not** the `process_artifacts_experimental`job; see the next section)
35-
* If it's still pending, you'll need to wait for it to finish. <sup>1</sup>
36-
4. Copy the build ID from the URL
37-
* e.g. the build ID for commit [e5d06e34b](https://github.com/facebook/react/commit/e5d06e34b) is [**124756**](https://circleci.com/gh/facebook/react/124756)
38-
5. Run the [`prepare-release-from-ci`](#prepare-release-from-ci) script with the build ID <sup>2</sup> you found:
33+
2. Copy the SHA (by clicking the 📋 button)
34+
5. Run the [`prepare-release-from-ci`](#prepare-release-from-ci) script with the SHA <sup>1</sup> you found:
3935
```sh
40-
scripts/release/prepare-release-from-ci.js --build=124756
36+
scripts/release/prepare-release-from-ci.js -r stable --commit=0e526bc
4137
```
4238

4339
Once the build has been checked out and tested locally, you're ready to publish it:
4440
```sh
4541
scripts/release/publish.js --tags next
4642
```
4743

48-
If the OTP code expires while publishing, re-run this command and answer "y" to the questions about whether it was expected for already published packages.
49-
50-
<sup>1: This is the most awkward part of cutting a release right now. We have plans to improve it.</sup><br/>
51-
<sup>2: You can omit the `build` param if you just want to release the latest commit as to "next".</sup>
44+
<sup>1: You can omit the `commit` param if you just want to release the latest commit as to "next".</sup>
5245

5346
## Publishing an Experimental Release
5447

5548
Experimental releases are special because they have additional features turned on.
5649

57-
The steps for publishing an experimental release are almost the same as for publishing a "next" release, except in step 3 you should choose the `process_artifacts_experimental ` job (instead of `process_artifacts`) <sup>1</sup>
50+
The steps for publishing an experimental release are almost the same as for publishing a "next" release except for the release channel (`-r`) flag.
5851

59-
For example, the experimental build ID for commit [e5d06e34b](https://github.com/facebook/react/commit/e5d06e34b) is [**124763**](https://circleci.com/gh/facebook/react/124763):
6052
```sh
61-
scripts/release/prepare-release-from-ci.js --build=124763
53+
scripts/release/prepare-release-from-ci.js -r experimental --commit=0e526bc
6254
```
6355

6456
Once the build has been checked out and tested locally, you're ready to publish it. When publishing an experimental release, use the `experimental` tag:
@@ -67,10 +59,6 @@ Once the build has been checked out and tested locally, you're ready to publish
6759
scripts/release/publish.js --tags experimental
6860
```
6961

70-
If the OTP code expires while publishing, re-run this command and answer "y" to the questions about whether it was expected for already published packages.
71-
72-
<sup>1: We have plans to make this less awkward. Ideally these releases will be published by a cron job.</sup>
73-
7462
## Publishing a Stable Release
7563

7664
Stable releases should always be created from the "next" channel. This encourages better testing of the actual release artifacts and reduces the chance of unintended changes accidentally being included in a stable release.
@@ -92,8 +80,6 @@ scripts/release/publish.js --tags latest
9280
scripts/release/publish.js --tags latest next
9381
```
9482

95-
If the OTP code expires while publishing, re-run this command and answer "y" to the questions about whether it was expected for already published packages.
96-
9783
After successfully publishing the release, follow the on-screen instructions to ensure that all of the appropriate post-release steps are executed.
9884

9985
<sup>1: You can omit the `version` param if you just want to promote the latest "next" candidate to stable.</sup>
@@ -145,9 +131,9 @@ Downloads build artifacts from Circle CI in preparation to be published to NPM a
145131
All artifacts built by Circle CI have already been unit-tested (both source and bundles) but these candidates should **always be manually tested** before being published. Upon completion, this script prints manual testing instructions.
146132

147133
#### Example usage
148-
To prepare the artifacts created by [Circle CI build 124756](https://circleci.com/gh/facebook/react/124756#artifacts/containers/0) you would run:
134+
To prepare the artifacts created by Circle CI for commit [0e526bc](https://github.com/facebook/react/commit/0e526bc) you would run:
149135
```sh
150-
scripts/release/prepare-release-from-ci.js --build=124756
136+
scripts/release/prepare-release-from-ci.js --commit=0e526bc -r stable
151137
```
152138

153139
## `prepare-release-from-npm`

scripts/release/download-experimental-build-commands/print-summary.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,23 @@
55
const clear = require('clear');
66
const {join, relative} = require('path');
77
const theme = require('../theme');
8+
const {getCommitFromCurrentBuild} = require('../utils');
89

9-
module.exports = ({build}) => {
10+
module.exports = async () => {
1011
const commandPath = relative(
1112
process.env.PWD,
1213
join(__dirname, '../download-experimental-build.js')
1314
);
1415

1516
clear();
1617

18+
const commit = await getCommitFromCurrentBuild();
19+
1720
const message = theme`
1821
{caution An experimental build has been downloaded!}
1922
2023
You can download this build again by running:
21-
{path ${commandPath}} --build={build ${build}}
24+
{path ${commandPath}} --commit={commit ${commit}}
2225
`;
2326

2427
console.log(message.replace(/\n +/g, '\n').trim());

scripts/release/download-experimental-build.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ const printSummary = require('./download-experimental-build-commands/print-summa
1717
const run = async () => {
1818
try {
1919
addDefaultParamValue('-r', '--releaseChannel', 'experimental');
20+
21+
// Default to the latest commit in master.
22+
// If this is a reproducible build (e.g. Firefox tester) a --commit will be specified.
2023
addDefaultParamValue(null, '--commit', 'master');
2124

2225
const params = await parseParams();

scripts/release/prepare-release-from-ci.js

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,25 +3,22 @@
33
'use strict';
44

55
const {join} = require('path');
6-
const {handleError} = require('./utils');
6+
const {addDefaultParamValue, handleError} = require('./utils');
77

88
const checkEnvironmentVariables = require('./shared-commands/check-environment-variables');
99
const downloadBuildArtifacts = require('./shared-commands/download-build-artifacts');
10-
const getLatestMasterBuildNumber = require('./shared-commands/get-latest-master-build-number');
1110
const parseParams = require('./shared-commands/parse-params');
1211
const printPrereleaseSummary = require('./shared-commands/print-prerelease-summary');
1312
const testPackagingFixture = require('./shared-commands/test-packaging-fixture');
1413
const testTracingFixture = require('./shared-commands/test-tracing-fixture');
1514

1615
const run = async () => {
1716
try {
17+
addDefaultParamValue(null, '--commit', 'master');
18+
1819
const params = await parseParams();
1920
params.cwd = join(__dirname, '..', '..');
2021

21-
if (!params.build) {
22-
params.build = await getLatestMasterBuildNumber(false);
23-
}
24-
2522
await checkEnvironmentVariables(params);
2623
await downloadBuildArtifacts(params);
2724

scripts/release/shared-commands/download-build-artifacts.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,9 @@ const run = async ({build, cwd, releaseChannel}) => {
5050
await exec(`cp -r ./build2/${sourceDir} ./build/node_modules`, {cwd});
5151
};
5252

53-
module.exports = async ({build, cwd, releaseChannel}) => {
53+
module.exports = async ({build, commit, cwd, releaseChannel}) => {
5454
return logPromise(
5555
run({build, cwd, releaseChannel}),
56-
theme`Downloading artifacts from Circle CI for build {build ${build}}`
56+
theme`Downloading artifacts from Circle CI for commit {commit ${commit}} (build {build ${build}})`
5757
);
5858
};

scripts/release/shared-commands/get-latest-master-build-number.js

Lines changed: 0 additions & 27 deletions
This file was deleted.

scripts/release/shared-commands/parse-params.js

Lines changed: 14 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,9 @@
44

55
const commandLineArgs = require('command-line-args');
66
const getBuildIdForCommit = require('../get-build-id-for-commit');
7+
const theme = require('../theme');
78

89
const paramDefinitions = [
9-
{
10-
name: 'build',
11-
type: Number,
12-
description:
13-
'Circle CI build identifier (e.g. https://circleci.com/gh/facebook/react/<build>)',
14-
defaultValue: null,
15-
},
1610
{
1711
name: 'commit',
1812
type: String,
@@ -37,29 +31,25 @@ const paramDefinitions = [
3731
module.exports = async () => {
3832
const params = commandLineArgs(paramDefinitions);
3933

40-
if (params.build !== null) {
41-
// TODO: Should we just remove the `build` param? Seems like `commit` is a
42-
// sufficient replacement.
43-
} else {
44-
if (params.commit === null) {
45-
console.error('Must provide either `build` or `commit`.');
46-
process.exit(1);
47-
}
48-
try {
49-
params.build = await getBuildIdForCommit(params.commit);
50-
} catch (error) {
51-
console.error(error.message);
52-
process.exit(1);
53-
}
54-
}
55-
5634
const channel = params.releaseChannel;
5735
if (channel !== 'experimental' && channel !== 'stable') {
5836
console.error(
59-
`Invalid release channel (-r) "${channel}". Must be "stable" or "experimental".`
37+
theme.error`Invalid release channel (-r) "${channel}". Must be "stable" or "experimental".`
6038
);
6139
process.exit(1);
6240
}
6341

42+
if (params.commit === null) {
43+
console.error(theme.error`No --commit param specified.`);
44+
process.exit(1);
45+
}
46+
47+
try {
48+
params.build = await getBuildIdForCommit(params.commit);
49+
} catch (error) {
50+
console.error(theme.error(error));
51+
process.exit(1);
52+
}
53+
6454
return params;
6555
};

scripts/release/theme.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ theme.package = theme.hex(colors.green);
1515
theme.version = theme.hex(colors.yellow);
1616
theme.tag = theme.hex(colors.yellow);
1717
theme.build = theme.hex(colors.yellow);
18+
theme.commit = theme.hex(colors.yellow);
1819
theme.error = theme.hex(colors.red).bold;
1920
theme.dimmed = theme.hex(colors.gray);
2021
theme.caution = theme.hex(colors.red).bold;

scripts/release/utils.js

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
const {exec} = require('child-process-promise');
44
const {createPatch} = require('diff');
55
const {hashElement} = require('folder-hash');
6-
const {readFileSync, writeFileSync} = require('fs');
6+
const {existsSync, readFileSync, writeFileSync} = require('fs');
77
const {readJson, writeJson} = require('fs-extra');
88
const http = require('request-promise-json');
99
const logUpdate = require('log-update');
@@ -47,6 +47,16 @@ const execRead = async (command, options) => {
4747
return stdout.trim();
4848
};
4949

50+
const extractCommitFromVersionNumber = version => {
51+
// Support stable version format e.g. "0.0.0-0e526bcec"
52+
// and experimental version format e.g. "0.0.0-experimental-0e526bcec"
53+
const match = version.match(/0\.0\.0\-([a-z]+\-){0,1}(.+)/);
54+
if (match === null) {
55+
throw Error(`Could not extra commit from version "${version}"`);
56+
}
57+
return match[2];
58+
};
59+
5060
const getArtifactsList = async buildID => {
5161
const buildMetadataURL = `https://circleci.com/api/v1.1/project/github/facebook/react/${buildID}?circle-token=${process.env.CIRCLE_CI_API_TOKEN}`;
5262
const buildMetadata = await http.get(buildMetadataURL, true);
@@ -115,6 +125,35 @@ const getChecksumForCurrentRevision = async cwd => {
115125
return hashedPackages.hash.slice(0, 7);
116126
};
117127

128+
const getCommitFromCurrentBuild = async () => {
129+
const cwd = join(__dirname, '..', '..');
130+
131+
// If this build includes a build-info.json file, extract the commit from it.
132+
// Otherwise fall back to parsing from the package version number.
133+
// This is important to make the build reproducible (e.g. by Mozilla reviewers).
134+
const buildInfoJSON = join(
135+
cwd,
136+
'build2',
137+
'oss-experimental',
138+
'react',
139+
'build-info.json'
140+
);
141+
if (existsSync(buildInfoJSON)) {
142+
const buildInfo = await readJson(buildInfoJSON);
143+
return buildInfo.commit;
144+
} else {
145+
const packageJSON = join(
146+
cwd,
147+
'build2',
148+
'oss-experimental',
149+
'react',
150+
'package.json'
151+
);
152+
const {version} = await readJson(packageJSON);
153+
return extractCommitFromVersionNumber(version);
154+
}
155+
};
156+
118157
const getPublicPackages = isExperimental => {
119158
if (isExperimental) {
120159
return [
@@ -270,6 +309,7 @@ module.exports = {
270309
getArtifactsList,
271310
getBuildInfo,
272311
getChecksumForCurrentRevision,
312+
getCommitFromCurrentBuild,
273313
getPublicPackages,
274314
handleError,
275315
logPromise,

0 commit comments

Comments
 (0)