@samitouri / QOS-React-2 / commits / 8e13f099ab

Overhauled release scripts and docs (#18569)

* Overhauled release scripts and docs

Brian Vaughn committed Apr 10, 2020 at 12:28 UTC 8e13f099ab0c820c6f97547ad08244340e074266
19 files changed +105 -39
scripts/release/README.md
+30 -24
@@ -4,16 +4,17 @@ The release process consists of several phases, each one represented by one of t
4
5 A typical release goes like this:
6 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. The release is then [**published to the `next` channel**](#publishing-next) using the [`prepare-next`](#prepare-next) 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 "next" release can be [**promoted to stable**](#publishing-a-stable-release)<sup>1</sup> using the [`prepare-stable`](#prepare-stable) and [`publish`](#publish) scripts. (This process is always manual.)
7 +2. The release is then [**published to the `next` channel**](#publishing-release) using the [`prepare-release-from-ci`](#prepare-release-from-ci) 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 + 1. The release may also be [**published to the `experimental` channel**](#publishing-an-experimental-release) using the the same scripts (but different build artifacts).
9 +3. Finally, a "next" release can be [**promoted to stable**](#publishing-a-stable-release)<sup>1</sup> using the [`prepare-release-from-npm`](#prepare-release-from-npm) and [`publish`](#publish) scripts. (This process is always manual.)
10
11 The high level process of creating releases is [documented below](#process). Individual scripts are documented as well:
11 -* [`create-next`](#create-next)
12 -* [`prepare-next`](#prepare-next)
13 -* [`prepare-stable`](#prepare-stable)
14 -* [`publish`](#publish)
12 +* [`build-release-locally`](#build-release-locally): Build a release locally from the checked out source code.
13 +* [`prepare-release-from-ci`](#prepare-release-from-ci): Download a pre-built release from CI.
14 +* [`prepare-release-from-npm`](#prepare-release-from-npm): Prepare an NPM "next" release to be published as a "stable" release.
15 +* [`publish`](#publish): Publish the downloaded (or prepared) release to NPM.
16
16 -<sup>Note that [**creating a patch release**](#creating-a-patch-release) has a slightly different process than a major/minor release.</sup>
17 +<sup>1. [**Creating a patch release**](#creating-a-patch-release) has a slightly different process than a major/minor release.</sup>
18
19 # Process
20
@@ -26,13 +27,13 @@ If this is your first time running the release scripts, go to the `scripts/relea
27 To prepare a build for a particular commit:
28 1. Choose a commit from [the commit log](https://github.com/facebook/react/commits/master).
29 2. Click the "“✓" icon and click the Circle CI "Details" link.
29 -3. Select the `build` job (**not** the `build_experimental` job; see the next section).
30 +3. Select the `process_artifacts ` job (**not** the `process_artifacts_experimental`job; see the next section)
31 * If it's still pending, you'll need to wait for it to finish. <sup>1</sup>
32 4. Copy the build ID from the URL
32 - * e.g. the build ID for commit [241c4467](https://github.com/facebook/react/commit/241c4467eef7c2a8858c96d5dfe4e8ef84c47bad) is [**80592**](https://circleci.com/gh/facebook/react/80592)
33 -5. Run the [`prepare-next`](#prepare-next) script with the build ID <sup>2</sup> you found:
33 + * e.g. the build ID for commit [e5d06e34b](https://github.com/facebook/react/commit/e5d06e34b) is [**124756**](https://circleci.com/gh/facebook/react/124756)
34 +5. Run the [`prepare-release-from-ci`](#prepare-release-from-ci) script with the build ID <sup>2</sup> you found:
35 ```sh
35 -scripts/release/prepare-next.js --build=80592
36 +scripts/release/prepare-release-from-ci.js --build=124756
37 ```
38
39 Once the build has been checked out and tested locally, you're ready to publish it:
@@ -49,9 +50,14 @@ If the OTP code expires while publishing, re-run this command and answer "y" to
50
51 Experimental releases are special because they have additional features turned on.
52
52 -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 `build_experimental` job instead of `build` <sup>1</sup> For example, the experimental build ID for commit [241c4467](https://github.com/facebook/react/commit/241c4467eef7c2a8858c96d5dfe4e8ef84c47bad) is [**80590**](https://circleci.com/gh/facebook/react/80590):
53 +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>
54
54 -When publishing an experimental release, use the `experimental` tag:
55 +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):
56 +```sh
57 +scripts/release/prepare-release-from-ci.js --build=124763
58 +```
59 +
60 +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:
61
62 ```sh
63 scripts/release/publish.js --tags experimental
@@ -65,10 +71,10 @@ If the OTP code expires while publishing, re-run this command and answer "y" to
71
72 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.
73
68 -To prepare a stable release, choose a "next" version and run the [`prepare-stable`](#prepare-stable) script <sup>1</sup>:
74 +To prepare a stable release, choose a "next" version and run the [`prepare-release-from-npm`](#prepare-release-from-npm) script <sup>1</sup>:
75
76 ```sh
71 -scripts/release/prepare-stable.js --version=0.0.0-241c4467e
77 +scripts/release/prepare-release-from-npm.js --version=0.0.0-241c4467e
78 ```
79
80 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.
@@ -107,13 +113,13 @@ Once you have cherry picked all of the commits you want to include in the releas
113 git push origin 16.8.3
114 ```
115
110 -Once CI is complete, follow the regular [**next**](#publishing-next) and [**promote to stable**](#publishing-a-stable-release) processes.
116 +Once CI is complete, follow the regular [**next**](#publishing-release) and [**promote to stable**](#publishing-a-stable-release) processes.
117
118 <sup>1: The `build-info.json` artifact can also be used to identify the appropriate commit (e.g. [unpkg.com/react@16.8.3/build-info.json](https://unpkg.com/react@16.8.3/build-info.json) shows us that react version 16.8.3 was created from commit [`29b7b775f`](https://github.com/facebook/react/commit/29b7b775f)).</sup>
119
120 # Scripts
121
116 -## `create-next`
122 +## `build-release-locally`
123 Creates a "next" build from the current (local) Git revision.
124
125 **This script is an escape hatch.** It allows a release to be created without pushing a commit to be verified by Circle CI. **It does not run any automated unit tests.** Testing is solely the responsibility of the release engineer.
@@ -123,21 +129,21 @@ Note that this script git-archives the React repo (at the current revision) to a
129 #### Example usage
130 To create a build from the current branch and revision:
131 ```sh
126 -scripts/release/create-next.js
132 +scripts/release/build-release-locally.js
133 ```
134
129 -## `prepare-next`
130 -Downloads build artifacts from Circle CI in preparation to be published to NPM as a "next" release.
135 +## `prepare-release-from-ci`
136 +Downloads build artifacts from Circle CI in preparation to be published to NPM as either a "next" or "experimental" release.
137
138 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.
139
140 #### Example usage
135 -To prepare the artifacts created by [Circle CI build 80592](https://circleci.com/gh/facebook/react/80592#artifacts/containers/0) you would run:
141 +To prepare the artifacts created by [Circle CI build 124756](https://circleci.com/gh/facebook/react/124756#artifacts/containers/0) you would run:
142 ```sh
137 -scripts/release/prepare-next.js --build=80592
143 +scripts/release/prepare-release-from-ci.js --build=124756
144 ```
145
140 -## `prepare-stable`
146 +## `prepare-release-from-npm`
147 Checks out a "next" release from NPM and prepares it to be published as a stable release.
148
149 This script prompts for new (stable) release versions for each public package and updates the package contents (both `package.json` and inline version numbers) to match. It also updates inter-package dependencies to account for the new versions.
@@ -147,7 +153,7 @@ This script prompts for new (stable) release versions for each public package an
153 #### Example usage
154 To promote the "next" release `0.0.0-241c4467e` (aka commit [241c4467e](https://github.com/facebook/react/commit/241c4467e)) to stable:
155 ```sh
150 -scripts/release/prepare-stable.js --version=0.0.0-241c4467e
156 +scripts/release/prepare-release-from-npm.js --version=0.0.0-241c4467e
157 ```
158
159 ## `publish`
scripts/release/build-release-locally-commands/add-build-info-json.js renamed
scripts/release/build-release-locally-commands/build-artifacts.js renamed
scripts/release/build-release-locally-commands/confirm-automated-testing.js renamed
scripts/release/build-release-locally-commands/copy-repo-to-temp-directory.js renamed
scripts/release/build-release-locally-commands/npm-pack-and-unpack.js renamed
scripts/release/build-release-locally-commands/update-version-numbers.js renamed
scripts/release/build-release-locally.js renamed
+6 -6
@@ -13,13 +13,13 @@ const {getBuildInfo, handleError} = require('./utils');
13 // It doesn't run all of the tests that the CI environment runs.
14 // You're expected to run those manually before publishing a release.
15
16 -const addBuildInfoJSON = require('./create-next-commands/add-build-info-json');
17 -const buildArtifacts = require('./create-next-commands/build-artifacts');
18 -const confirmAutomatedTesting = require('./create-next-commands/confirm-automated-testing');
19 -const copyRepoToTempDirectory = require('./create-next-commands/copy-repo-to-temp-directory');
20 -const npmPackAndUnpack = require('./create-next-commands/npm-pack-and-unpack');
16 +const addBuildInfoJSON = require('./build-release-locally-commands/add-build-info-json');
17 +const buildArtifacts = require('./build-release-locally-commands/build-artifacts');
18 +const confirmAutomatedTesting = require('./build-release-locally-commands/confirm-automated-testing');
19 +const copyRepoToTempDirectory = require('./build-release-locally-commands/copy-repo-to-temp-directory');
20 +const npmPackAndUnpack = require('./build-release-locally-commands/npm-pack-and-unpack');
21 const printPrereleaseSummary = require('./shared-commands/print-prerelease-summary');
22 -const updateVersionNumbers = require('./create-next-commands/update-version-numbers');
22 +const updateVersionNumbers = require('./build-release-locally-commands/update-version-numbers');
23
24 const run = async () => {
25 try {
scripts/release/build-release.js new
+57
@@ -0,0 +1,57 @@
1 +#!/usr/bin/env node
2 +
3 +'use strict';
4 +
5 +const {tmpdir} = require('os');
6 +const {join} = require('path');
7 +const {getBuildInfo, handleError} = require('./utils');
8 +
9 +// This script is an escape hatch!
10 +// It exists for special case manual builds.
11 +// The typical suggested release process is to create a "next" build from a CI artifact.
12 +// This build script is optimized for speed and simplicity.
13 +// It doesn't run all of the tests that the CI environment runs.
14 +// You're expected to run those manually before publishing a release.
15 +
16 +const addBuildInfoJSON = require('./build-release-locally-commands/add-build-info-json');
17 +const buildArtifacts = require('./build-release-locally-commands/build-artifacts');
18 +const confirmAutomatedTesting = require('./build-release-locally-commands/confirm-automated-testing');
19 +const copyRepoToTempDirectory = require('./build-release-locally-commands/copy-repo-to-temp-directory');
20 +const npmPackAndUnpack = require('./build-release-locally-commands/npm-pack-and-unpack');
21 +const printPrereleaseSummary = require('./shared-commands/print-prerelease-summary');
22 +const updateVersionNumbers = require('./build-release-locally-commands/update-version-numbers');
23 +
24 +const run = async () => {
25 + try {
26 + const cwd = join(__dirname, '..', '..');
27 + const {
28 + branch,
29 + checksum,
30 + commit,
31 + reactVersion,
32 + version,
33 + } = await getBuildInfo();
34 + const tempDirectory = join(tmpdir(), `react-${commit}`);
35 + const params = {
36 + branch,
37 + checksum,
38 + commit,
39 + cwd,
40 + reactVersion,
41 + tempDirectory,
42 + version,
43 + };
44 +
45 + await confirmAutomatedTesting(params);
46 + await copyRepoToTempDirectory(params);
47 + await updateVersionNumbers(params);
48 + await addBuildInfoJSON(params);
49 + await buildArtifacts(params);
50 + await npmPackAndUnpack(params);
51 + await printPrereleaseSummary(params, false);
52 + } catch (error) {
53 + handleError(error);
54 + }
55 +};
56 +
57 +run();
scripts/release/ci-add-build-info-json.js
+1 -1
@@ -7,7 +7,7 @@
7 // It exists to share code between the Node release scripts and CI bash scripts.
8
9 // IMPORTANT:
10 -// Changes below should be mirrored in ./create-next-commands/add-build-info-json.js
10 +// Changes below should be mirrored in ./build-release-locally-commands/add-build-info-json.js
11
12 const {exec} = require('child_process');
13 const {existsSync} = require('fs');
scripts/release/prepare-release-from-ci.js renamed
scripts/release/prepare-release-from-npm-commands/check-out-packages.js renamed
scripts/release/prepare-release-from-npm-commands/confirm-stable-version-numbers.js renamed
scripts/release/prepare-release-from-npm-commands/get-latest-next-version.js renamed
scripts/release/prepare-release-from-npm-commands/guess-stable-version-numbers.js renamed
scripts/release/prepare-release-from-npm-commands/parse-params.js renamed
scripts/release/prepare-release-from-npm-commands/update-stable-version-numbers.js renamed
scripts/release/prepare-release-from-npm.js renamed
+6 -6
@@ -5,15 +5,15 @@
5 const {join} = require('path');
6 const {getPublicPackages, handleError} = require('./utils');
7
8 -const checkOutPackages = require('./prepare-stable-commands/check-out-packages');
9 -const confirmStableVersionNumbers = require('./prepare-stable-commands/confirm-stable-version-numbers');
10 -const getLatestNextVersion = require('./prepare-stable-commands/get-latest-next-version');
11 -const guessStableVersionNumbers = require('./prepare-stable-commands/guess-stable-version-numbers');
12 -const parseParams = require('./prepare-stable-commands/parse-params');
8 +const checkOutPackages = require('./prepare-release-from-npm-commands/check-out-packages');
9 +const confirmStableVersionNumbers = require('./prepare-release-from-npm-commands/confirm-stable-version-numbers');
10 +const getLatestNextVersion = require('./prepare-release-from-npm-commands/get-latest-next-version');
11 +const guessStableVersionNumbers = require('./prepare-release-from-npm-commands/guess-stable-version-numbers');
12 +const parseParams = require('./prepare-release-from-npm-commands/parse-params');
13 const printPrereleaseSummary = require('./shared-commands/print-prerelease-summary');
14 const testPackagingFixture = require('./shared-commands/test-packaging-fixture');
15 const testTracingFixture = require('./shared-commands/test-tracing-fixture');
16 -const updateStableVersionNumbers = require('./prepare-stable-commands/update-stable-version-numbers');
16 +const updateStableVersionNumbers = require('./prepare-release-from-npm-commands/update-stable-version-numbers');
17 const theme = require('./theme');
18
19 const run = async () => {
scripts/release/snapshot-test.js
+5 -2
@@ -25,7 +25,10 @@ const run = async () => {
25 // https://circleci.com/gh/facebook/react/12707
26 let promise = spawn(
27 'node',
28 - ['./scripts/release/prepare-next.js', `--build=${CIRCLE_CI_BUILD}`],
28 + [
29 + './scripts/release/prepare-release-from-ci.js',
30 + `--build=${CIRCLE_CI_BUILD}`,
31 + ],
32 defaultOptions
33 );
34 logPromise(
@@ -40,7 +43,7 @@ const run = async () => {
43 promise = spawn(
44 'node',
45 [
43 - './scripts/release/prepare-stable.js',
46 + './scripts/release/prepare-release-from-npm.js',
47 `--version=0.0.0-${COMMIT}`,
48 '--local',
49 ],