Skip to content

Commit

Permalink
Release scripts documentation (#14863)
Browse files Browse the repository at this point in the history
* Improve release script process documentation
* Improved pre-publish instructions/message based on feedback
* Added reminder to attach build artifacts to GitHub release
  • Loading branch information
bvaughn authored Feb 15, 2019
1 parent ab7a67b commit fad0842
Show file tree
Hide file tree
Showing 8 changed files with 96 additions and 44 deletions.
50 changes: 47 additions & 3 deletions scripts/release/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,59 @@ The release process consists of several phases, each one represented by one of t

A typical release goes like this:
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.
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).)
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.)
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).)
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.)

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

# Process

## Publishing a Canary

Canaries are meant to be lightweight and published often. In most cases, canaries can be published using artifacts built by Circle CI.

To prepare a canary for a particular commit:
1. Choose a commit from [the commit log](https://github.com/facebook/react/commits/master).
2. Click the "“✓" icon and click the Circle CI "Details" link.
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**).
5. Run the [`prepare-canary`](#prepare-canary) script with the build ID you found <sup>1</sup>:
```sh
scripts/release/prepare-canary.js --build=13471
```

Once the canary has been checked out and tested locally, you're ready to publish it:
```sh
scripts/release/publish.js --tags canary
```

<sup>1: You can omit the `build` param if you just want to release the latest commit as a canary.</sup>

## Publishing a Stable Release

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.

To prepare a stable release, choose a canary version and run the [`prepare-stable`](#prepare-stable) script <sup>1</sup>:

```sh
scripts/release/prepare-stable.js --version=0.0.0-5bf84d292
```

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.

Once this step is complete, you're ready to publish the release:

```sh
scripts/release/publish.js --tags next latest
```

<sup>1: You can omit the `version` param if you just want to promote the latest canary to stable.</sup>

# Scripts

## `create-canary`
Creates a canary build from the current (local) Git revision.

Expand Down
2 changes: 1 addition & 1 deletion scripts/release/create-canary.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ const run = async () => {
await addBuildInfoJSON(params);
await buildArtifacts(params);
await npmPackAndUnpack(params);
await printPrereleaseSummary(params);
await printPrereleaseSummary(params, false);
} catch (error) {
handleError(error);
}
Expand Down
2 changes: 1 addition & 1 deletion scripts/release/prepare-canary.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ const run = async () => {
await testTracingFixture(params);
}

await printPrereleaseSummary(params);
await printPrereleaseSummary(params, false);
} catch (error) {
handleError(error);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#!/usr/bin/env node

'use strict';

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

const run = async () => {
const version = await execRead('npm info react@canary version');

return version;
};

module.exports = async params => {
return logPromise(run(params), 'Determining latest canary release version');
};
25 changes: 0 additions & 25 deletions scripts/release/prepare-stable-commands/parse-params.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
'use strict';

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

const paramDefinitions = [
{
Expand All @@ -29,29 +28,5 @@ const paramDefinitions = [
module.exports = () => {
const params = commandLineArgs(paramDefinitions);

if (!params.version) {
const usage = commandLineUsage([
{
content: 'Prepare a published canary release to be promoted to stable.',
},
{
header: 'Options',
optionList: paramDefinitions,
},
{
header: 'Examples',
content: [
{
desc: 'Example:',
example:
'$ ./prepare-stable.js [bold]{--version=}[underline]{0.0.0-ddaf2b07c}',
},
],
},
]);
console.log(usage);
process.exit(1);
}

return params;
};
7 changes: 6 additions & 1 deletion scripts/release/prepare-stable.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const {getPublicPackages, handleError} = require('./utils');

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

if (!params.version) {
params.version = await getLatestCanaryVersion();
}

await checkOutPackages(params);
await guessStableVersionNumbers(params, versionsMap);
await confirmStableVersionNumbers(params, versionsMap);
Expand All @@ -35,7 +40,7 @@ const run = async () => {
await testTracingFixture(params);
}

await printPrereleaseSummary(params);
await printPrereleaseSummary(params, true);
} catch (error) {
handleError(error);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,10 @@ const run = async ({cwd, packages, tags}) => {
console.log(theme.command` git push origin --tags`);

console.log();
console.log(theme.header`Lastly, please fill in the release on GitHub:`);
console.log(
theme.header`Lastly, please fill in the release on GitHub. ` +
theme`Don't forget to attach build artifacts from {path build/node_modules/}`
);
console.log(
theme.link`https://github.com/facebook/react/releases/tag/v%s`,
version
Expand Down
34 changes: 22 additions & 12 deletions scripts/release/shared-commands/print-prerelease-summary.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,26 +6,36 @@ const clear = require('clear');
const {join, relative} = require('path');
const theme = require('../theme');

module.exports = ({cwd}) => {
module.exports = ({cwd}, isStableRelease) => {
const publishPath = relative(
process.env.PWD,
join(__dirname, '../publish.js')
);

clear();

console.log(
theme`
{caution A release candidate has been prepared but you're not done yet!}
let message;
if (isStableRelease) {
message = theme`
{caution A stable release candidate has been prepared!}
You can review the contents of this release in {path ./build/node_modules/}
You can review the contents of this release in {path build/node_modules/}
{header Before publishing, please smoke test the packages!}
{header Before publishing, consider testing this release locally with create-react-app!}
Once you have finished smoke testing, you can publish this release by running:
{path ${publishPath}}
`
.replace(/\n +/g, '\n')
.trim()
);
You can publish this release by running:
{path ${publishPath}}
`;
} else {
message = theme`
{caution A canary release candidate has been prepared!}
You can review the contents of this release in {path build/node_modules/}
You can publish this release by running:
{path ${publishPath}}
`;
}

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

0 comments on commit fad0842

Please sign in to comment.