Skip to content

Commit fad0842

Browse files
authored
Release scripts documentation (#14863)
* Improve release script process documentation * Improved pre-publish instructions/message based on feedback * Added reminder to attach build artifacts to GitHub release
1 parent ab7a67b commit fad0842

File tree

8 files changed

+96
-44
lines changed

8 files changed

+96
-44
lines changed

scripts/release/README.md

Lines changed: 47 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,59 @@ The release process consists of several phases, each one represented by one of t
44

55
A typical release goes like this:
66
1. When a commit is pushed to the React repo, [Circle CI](https://circleci.com/gh/facebook/react/) will build all release bundles and run unit tests against both the source code and the built bundles.
7-
2. Next the release is published as a canary using the [`prepare-canary`](#prepare-canary) and [`publish`](#publish) scripts. (Currently this process is manual but might be automated in the future using [GitHub "actions"](https://github.com/features/actions).)
8-
3. Finally, a canary releases can be promoted to stable using the [`prepare-stable`](#prepare-stable) and [`publish`](#publish) scripts. (This process is always manual.)
7+
2. Next the release is [**published as a canary**](#publishing-a-canary) using the [`prepare-canary`](#prepare-canary) and [`publish`](#publish) scripts. (Currently this process is manual but might be automated in the future using [GitHub "actions"](https://github.com/features/actions).)
8+
3. Finally, a canary releases can be [**promoted to stable**](#publishing-a-stable-release) using the [`prepare-stable`](#prepare-stable) and [`publish`](#publish) scripts. (This process is always manual.)
99

10-
One or more release scripts are used for each of the above phases. Learn more about these scripts below:
10+
The high level process of creating releases is [documented below](#process). Individual scripts are documented as well:
1111
* [`create-canary`](#create-canary)
1212
* [`prepare-canary`](#prepare-canary)
1313
* [`prepare-stable`](#prepare-stable)
1414
* [`publish`](#publish)
1515

16+
# Process
17+
18+
## Publishing a Canary
19+
20+
Canaries are meant to be lightweight and published often. In most cases, canaries can be published using artifacts built by Circle CI.
21+
22+
To prepare a canary for a particular commit:
23+
1. Choose a commit from [the commit log](https://github.com/facebook/react/commits/master).
24+
2. Click the "“✓" icon and click the Circle CI "Details" link.
25+
4. Copy the build ID from the URL (e.g. the build ID for [circleci.com/gh/facebook/react/13471](https://circleci.com/gh/facebook/react/13471) is **13471**).
26+
5. Run the [`prepare-canary`](#prepare-canary) script with the build ID you found <sup>1</sup>:
27+
```sh
28+
scripts/release/prepare-canary.js --build=13471
29+
```
30+
31+
Once the canary has been checked out and tested locally, you're ready to publish it:
32+
```sh
33+
scripts/release/publish.js --tags canary
34+
```
35+
36+
<sup>1: You can omit the `build` param if you just want to release the latest commit as a canary.</sup>
37+
38+
## Publishing a Stable Release
39+
40+
Stable releases should always be created from a previously-released canary. This encourages better testing of the actual release artifacts and reduces the chance of unintended changes accidentally being included in a stable release.
41+
42+
To prepare a stable release, choose a canary version and run the [`prepare-stable`](#prepare-stable) script <sup>1</sup>:
43+
44+
```sh
45+
scripts/release/prepare-stable.js --version=0.0.0-5bf84d292
46+
```
47+
48+
This script will prompt you to select stable version numbers for each of the packages. It will update the package JSON versions (and dependencies) based on the numbers you select.
49+
50+
Once this step is complete, you're ready to publish the release:
51+
52+
```sh
53+
scripts/release/publish.js --tags next latest
54+
```
55+
56+
<sup>1: You can omit the `version` param if you just want to promote the latest canary to stable.</sup>
57+
58+
# Scripts
59+
1660
## `create-canary`
1761
Creates a canary build from the current (local) Git revision.
1862

scripts/release/create-canary.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ const run = async () => {
4848
await addBuildInfoJSON(params);
4949
await buildArtifacts(params);
5050
await npmPackAndUnpack(params);
51-
await printPrereleaseSummary(params);
51+
await printPrereleaseSummary(params, false);
5252
} catch (error) {
5353
handleError(error);
5454
}

scripts/release/prepare-canary.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ const run = async () => {
3131
await testTracingFixture(params);
3232
}
3333

34-
await printPrereleaseSummary(params);
34+
await printPrereleaseSummary(params, false);
3535
} catch (error) {
3636
handleError(error);
3737
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#!/usr/bin/env node
2+
3+
'use strict';
4+
5+
const {execRead, logPromise} = require('../utils');
6+
7+
const run = async () => {
8+
const version = await execRead('npm info react@canary version');
9+
10+
return version;
11+
};
12+
13+
module.exports = async params => {
14+
return logPromise(run(params), 'Determining latest canary release version');
15+
};

scripts/release/prepare-stable-commands/parse-params.js

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

55
const commandLineArgs = require('command-line-args');
6-
const commandLineUsage = require('command-line-usage');
76

87
const paramDefinitions = [
98
{
@@ -29,29 +28,5 @@ const paramDefinitions = [
2928
module.exports = () => {
3029
const params = commandLineArgs(paramDefinitions);
3130

32-
if (!params.version) {
33-
const usage = commandLineUsage([
34-
{
35-
content: 'Prepare a published canary release to be promoted to stable.',
36-
},
37-
{
38-
header: 'Options',
39-
optionList: paramDefinitions,
40-
},
41-
{
42-
header: 'Examples',
43-
content: [
44-
{
45-
desc: 'Example:',
46-
example:
47-
'$ ./prepare-stable.js [bold]{--version=}[underline]{0.0.0-ddaf2b07c}',
48-
},
49-
],
50-
},
51-
]);
52-
console.log(usage);
53-
process.exit(1);
54-
}
55-
5631
return params;
5732
};

scripts/release/prepare-stable.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ const {getPublicPackages, handleError} = require('./utils');
77

88
const checkOutPackages = require('./prepare-stable-commands/check-out-packages');
99
const confirmStableVersionNumbers = require('./prepare-stable-commands/confirm-stable-version-numbers');
10+
const getLatestCanaryVersion = require('./prepare-stable-commands/get-latest-canary-version');
1011
const guessStableVersionNumbers = require('./prepare-stable-commands/guess-stable-version-numbers');
1112
const parseParams = require('./prepare-stable-commands/parse-params');
1213
const printPrereleaseSummary = require('./shared-commands/print-prerelease-summary');
@@ -25,6 +26,10 @@ const run = async () => {
2526
// The developer running the release later confirms or overrides each version.
2627
const versionsMap = new Map();
2728

29+
if (!params.version) {
30+
params.version = await getLatestCanaryVersion();
31+
}
32+
2833
await checkOutPackages(params);
2934
await guessStableVersionNumbers(params, versionsMap);
3035
await confirmStableVersionNumbers(params, versionsMap);
@@ -35,7 +40,7 @@ const run = async () => {
3540
await testTracingFixture(params);
3641
}
3742

38-
await printPrereleaseSummary(params);
43+
await printPrereleaseSummary(params, true);
3944
} catch (error) {
4045
handleError(error);
4146
}

scripts/release/publish-commands/print-follow-up-instructions.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,10 @@ const run = async ({cwd, packages, tags}) => {
7878
console.log(theme.command` git push origin --tags`);
7979

8080
console.log();
81-
console.log(theme.header`Lastly, please fill in the release on GitHub:`);
81+
console.log(
82+
theme.header`Lastly, please fill in the release on GitHub. ` +
83+
theme`Don't forget to attach build artifacts from {path build/node_modules/}`
84+
);
8285
console.log(
8386
theme.link`https://github.com/facebook/react/releases/tag/v%s`,
8487
version

scripts/release/shared-commands/print-prerelease-summary.js

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,26 +6,36 @@ const clear = require('clear');
66
const {join, relative} = require('path');
77
const theme = require('../theme');
88

9-
module.exports = ({cwd}) => {
9+
module.exports = ({cwd}, isStableRelease) => {
1010
const publishPath = relative(
1111
process.env.PWD,
1212
join(__dirname, '../publish.js')
1313
);
1414

1515
clear();
1616

17-
console.log(
18-
theme`
19-
{caution A release candidate has been prepared but you're not done yet!}
17+
let message;
18+
if (isStableRelease) {
19+
message = theme`
20+
{caution A stable release candidate has been prepared!}
2021
21-
You can review the contents of this release in {path ./build/node_modules/}
22+
You can review the contents of this release in {path build/node_modules/}
2223
23-
{header Before publishing, please smoke test the packages!}
24+
{header Before publishing, consider testing this release locally with create-react-app!}
2425
25-
Once you have finished smoke testing, you can publish this release by running:
26-
{path ${publishPath}}
27-
`
28-
.replace(/\n +/g, '\n')
29-
.trim()
30-
);
26+
You can publish this release by running:
27+
{path ${publishPath}}
28+
`;
29+
} else {
30+
message = theme`
31+
{caution A canary release candidate has been prepared!}
32+
33+
You can review the contents of this release in {path build/node_modules/}
34+
35+
You can publish this release by running:
36+
{path ${publishPath}}
37+
`;
38+
}
39+
40+
console.log(message.replace(/\n +/g, '\n').trim());
3141
};

0 commit comments

Comments
 (0)