mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
Remove --build flag from release scripts (#20723)
Also update instructions to match recent script changes. Also add reproducible commit SHA to post download instructions to support publishing the Firefox DevTools extension.
This commit is contained in:
@@ -30,14 +30,10 @@ The sections below include meaningful `--tags` in the instructions. However, kee
|
||||
|
||||
To prepare a build 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.
|
||||
3. Select the `process_artifacts ` job (**not** the `process_artifacts_experimental`job; see the next section)
|
||||
* If it's still pending, you'll need to wait for it to finish. <sup>1</sup>
|
||||
4. Copy the build ID from the URL
|
||||
* e.g. the build ID for commit [e5d06e34b](https://github.com/facebook/react/commit/e5d06e34b) is [**124756**](https://circleci.com/gh/facebook/react/124756)
|
||||
5. Run the [`prepare-release-from-ci`](#prepare-release-from-ci) script with the build ID <sup>2</sup> you found:
|
||||
2. Copy the SHA (by clicking the 📋 button)
|
||||
5. Run the [`prepare-release-from-ci`](#prepare-release-from-ci) script with the SHA <sup>1</sup> you found:
|
||||
```sh
|
||||
scripts/release/prepare-release-from-ci.js --build=124756
|
||||
scripts/release/prepare-release-from-ci.js -r stable --commit=0e526bc
|
||||
```
|
||||
|
||||
Once the build has been checked out and tested locally, you're ready to publish it:
|
||||
@@ -45,20 +41,16 @@ Once the build has been checked out and tested locally, you're ready to publish
|
||||
scripts/release/publish.js --tags next
|
||||
```
|
||||
|
||||
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.
|
||||
|
||||
<sup>1: This is the most awkward part of cutting a release right now. We have plans to improve it.</sup><br/>
|
||||
<sup>2: You can omit the `build` param if you just want to release the latest commit as to "next".</sup>
|
||||
<sup>1: You can omit the `commit` param if you just want to release the latest commit as to "next".</sup>
|
||||
|
||||
## Publishing an Experimental Release
|
||||
|
||||
Experimental releases are special because they have additional features turned on.
|
||||
|
||||
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>
|
||||
The steps for publishing an experimental release are almost the same as for publishing a "next" release except for the release channel (`-r`) flag.
|
||||
|
||||
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):
|
||||
```sh
|
||||
scripts/release/prepare-release-from-ci.js --build=124763
|
||||
scripts/release/prepare-release-from-ci.js -r experimental --commit=0e526bc
|
||||
```
|
||||
|
||||
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
|
||||
scripts/release/publish.js --tags experimental
|
||||
```
|
||||
|
||||
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.
|
||||
|
||||
<sup>1: We have plans to make this less awkward. Ideally these releases will be published by a cron job.</sup>
|
||||
|
||||
## Publishing a Stable Release
|
||||
|
||||
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
|
||||
scripts/release/publish.js --tags latest next
|
||||
```
|
||||
|
||||
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.
|
||||
|
||||
After successfully publishing the release, follow the on-screen instructions to ensure that all of the appropriate post-release steps are executed.
|
||||
|
||||
<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
|
||||
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.
|
||||
|
||||
#### Example usage
|
||||
To prepare the artifacts created by [Circle CI build 124756](https://circleci.com/gh/facebook/react/124756#artifacts/containers/0) you would run:
|
||||
To prepare the artifacts created by Circle CI for commit [0e526bc](https://github.com/facebook/react/commit/0e526bc) you would run:
|
||||
```sh
|
||||
scripts/release/prepare-release-from-ci.js --build=124756
|
||||
scripts/release/prepare-release-from-ci.js --commit=0e526bc -r stable
|
||||
```
|
||||
|
||||
## `prepare-release-from-npm`
|
||||
|
||||
@@ -5,8 +5,9 @@
|
||||
const clear = require('clear');
|
||||
const {join, relative} = require('path');
|
||||
const theme = require('../theme');
|
||||
const {getCommitFromCurrentBuild} = require('../utils');
|
||||
|
||||
module.exports = ({build}) => {
|
||||
module.exports = async () => {
|
||||
const commandPath = relative(
|
||||
process.env.PWD,
|
||||
join(__dirname, '../download-experimental-build.js')
|
||||
@@ -14,11 +15,13 @@ module.exports = ({build}) => {
|
||||
|
||||
clear();
|
||||
|
||||
const commit = await getCommitFromCurrentBuild();
|
||||
|
||||
const message = theme`
|
||||
{caution An experimental build has been downloaded!}
|
||||
|
||||
You can download this build again by running:
|
||||
{path ${commandPath}} --build={build ${build}}
|
||||
{path ${commandPath}} --commit={commit ${commit}}
|
||||
`;
|
||||
|
||||
console.log(message.replace(/\n +/g, '\n').trim());
|
||||
|
||||
@@ -17,6 +17,9 @@ const printSummary = require('./download-experimental-build-commands/print-summa
|
||||
const run = async () => {
|
||||
try {
|
||||
addDefaultParamValue('-r', '--releaseChannel', 'experimental');
|
||||
|
||||
// Default to the latest commit in master.
|
||||
// If this is a reproducible build (e.g. Firefox tester) a --commit will be specified.
|
||||
addDefaultParamValue(null, '--commit', 'master');
|
||||
|
||||
const params = await parseParams();
|
||||
|
||||
@@ -3,11 +3,10 @@
|
||||
'use strict';
|
||||
|
||||
const {join} = require('path');
|
||||
const {handleError} = require('./utils');
|
||||
const {addDefaultParamValue, handleError} = require('./utils');
|
||||
|
||||
const checkEnvironmentVariables = require('./shared-commands/check-environment-variables');
|
||||
const downloadBuildArtifacts = require('./shared-commands/download-build-artifacts');
|
||||
const getLatestMasterBuildNumber = require('./shared-commands/get-latest-master-build-number');
|
||||
const parseParams = require('./shared-commands/parse-params');
|
||||
const printPrereleaseSummary = require('./shared-commands/print-prerelease-summary');
|
||||
const testPackagingFixture = require('./shared-commands/test-packaging-fixture');
|
||||
@@ -15,13 +14,11 @@ const testTracingFixture = require('./shared-commands/test-tracing-fixture');
|
||||
|
||||
const run = async () => {
|
||||
try {
|
||||
addDefaultParamValue(null, '--commit', 'master');
|
||||
|
||||
const params = await parseParams();
|
||||
params.cwd = join(__dirname, '..', '..');
|
||||
|
||||
if (!params.build) {
|
||||
params.build = await getLatestMasterBuildNumber(false);
|
||||
}
|
||||
|
||||
await checkEnvironmentVariables(params);
|
||||
await downloadBuildArtifacts(params);
|
||||
|
||||
|
||||
@@ -50,9 +50,9 @@ const run = async ({build, cwd, releaseChannel}) => {
|
||||
await exec(`cp -r ./build2/${sourceDir} ./build/node_modules`, {cwd});
|
||||
};
|
||||
|
||||
module.exports = async ({build, cwd, releaseChannel}) => {
|
||||
module.exports = async ({build, commit, cwd, releaseChannel}) => {
|
||||
return logPromise(
|
||||
run({build, cwd, releaseChannel}),
|
||||
theme`Downloading artifacts from Circle CI for build {build ${build}}`
|
||||
theme`Downloading artifacts from Circle CI for commit {commit ${commit}} (build {build ${build}})`
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
'use strict';
|
||||
|
||||
const http = require('request-promise-json');
|
||||
const {logPromise} = require('../utils');
|
||||
|
||||
const run = async () => {
|
||||
// https://circleci.com/docs/api/#recent-builds-for-a-project-branch
|
||||
const metadataURL = `https://circleci.com/api/v1.1/project/github/facebook/react/tree/master`;
|
||||
const metadata = await http.get(metadataURL, true);
|
||||
const build = metadata.find(
|
||||
entry =>
|
||||
entry.branch === 'master' &&
|
||||
entry.status === 'success' &&
|
||||
entry.workflows.job_name === 'process_artifacts_combined'
|
||||
).build_num;
|
||||
|
||||
return build;
|
||||
};
|
||||
|
||||
module.exports = async params => {
|
||||
return logPromise(
|
||||
run(params),
|
||||
'Determining latest Circle CI for the master branch'
|
||||
);
|
||||
};
|
||||
@@ -4,15 +4,9 @@
|
||||
|
||||
const commandLineArgs = require('command-line-args');
|
||||
const getBuildIdForCommit = require('../get-build-id-for-commit');
|
||||
const theme = require('../theme');
|
||||
|
||||
const paramDefinitions = [
|
||||
{
|
||||
name: 'build',
|
||||
type: Number,
|
||||
description:
|
||||
'Circle CI build identifier (e.g. https://circleci.com/gh/facebook/react/<build>)',
|
||||
defaultValue: null,
|
||||
},
|
||||
{
|
||||
name: 'commit',
|
||||
type: String,
|
||||
@@ -37,29 +31,25 @@ const paramDefinitions = [
|
||||
module.exports = async () => {
|
||||
const params = commandLineArgs(paramDefinitions);
|
||||
|
||||
if (params.build !== null) {
|
||||
// TODO: Should we just remove the `build` param? Seems like `commit` is a
|
||||
// sufficient replacement.
|
||||
} else {
|
||||
if (params.commit === null) {
|
||||
console.error('Must provide either `build` or `commit`.');
|
||||
process.exit(1);
|
||||
}
|
||||
try {
|
||||
params.build = await getBuildIdForCommit(params.commit);
|
||||
} catch (error) {
|
||||
console.error(error.message);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
const channel = params.releaseChannel;
|
||||
if (channel !== 'experimental' && channel !== 'stable') {
|
||||
console.error(
|
||||
`Invalid release channel (-r) "${channel}". Must be "stable" or "experimental".`
|
||||
theme.error`Invalid release channel (-r) "${channel}". Must be "stable" or "experimental".`
|
||||
);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
if (params.commit === null) {
|
||||
console.error(theme.error`No --commit param specified.`);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
try {
|
||||
params.build = await getBuildIdForCommit(params.commit);
|
||||
} catch (error) {
|
||||
console.error(theme.error(error));
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
return params;
|
||||
};
|
||||
|
||||
@@ -15,6 +15,7 @@ theme.package = theme.hex(colors.green);
|
||||
theme.version = theme.hex(colors.yellow);
|
||||
theme.tag = theme.hex(colors.yellow);
|
||||
theme.build = theme.hex(colors.yellow);
|
||||
theme.commit = theme.hex(colors.yellow);
|
||||
theme.error = theme.hex(colors.red).bold;
|
||||
theme.dimmed = theme.hex(colors.gray);
|
||||
theme.caution = theme.hex(colors.red).bold;
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
const {exec} = require('child-process-promise');
|
||||
const {createPatch} = require('diff');
|
||||
const {hashElement} = require('folder-hash');
|
||||
const {readFileSync, writeFileSync} = require('fs');
|
||||
const {existsSync, readFileSync, writeFileSync} = require('fs');
|
||||
const {readJson, writeJson} = require('fs-extra');
|
||||
const http = require('request-promise-json');
|
||||
const logUpdate = require('log-update');
|
||||
@@ -47,6 +47,16 @@ const execRead = async (command, options) => {
|
||||
return stdout.trim();
|
||||
};
|
||||
|
||||
const extractCommitFromVersionNumber = version => {
|
||||
// Support stable version format e.g. "0.0.0-0e526bcec"
|
||||
// and experimental version format e.g. "0.0.0-experimental-0e526bcec"
|
||||
const match = version.match(/0\.0\.0\-([a-z]+\-){0,1}(.+)/);
|
||||
if (match === null) {
|
||||
throw Error(`Could not extra commit from version "${version}"`);
|
||||
}
|
||||
return match[2];
|
||||
};
|
||||
|
||||
const getArtifactsList = async buildID => {
|
||||
const buildMetadataURL = `https://circleci.com/api/v1.1/project/github/facebook/react/${buildID}?circle-token=${process.env.CIRCLE_CI_API_TOKEN}`;
|
||||
const buildMetadata = await http.get(buildMetadataURL, true);
|
||||
@@ -115,6 +125,35 @@ const getChecksumForCurrentRevision = async cwd => {
|
||||
return hashedPackages.hash.slice(0, 7);
|
||||
};
|
||||
|
||||
const getCommitFromCurrentBuild = async () => {
|
||||
const cwd = join(__dirname, '..', '..');
|
||||
|
||||
// If this build includes a build-info.json file, extract the commit from it.
|
||||
// Otherwise fall back to parsing from the package version number.
|
||||
// This is important to make the build reproducible (e.g. by Mozilla reviewers).
|
||||
const buildInfoJSON = join(
|
||||
cwd,
|
||||
'build2',
|
||||
'oss-experimental',
|
||||
'react',
|
||||
'build-info.json'
|
||||
);
|
||||
if (existsSync(buildInfoJSON)) {
|
||||
const buildInfo = await readJson(buildInfoJSON);
|
||||
return buildInfo.commit;
|
||||
} else {
|
||||
const packageJSON = join(
|
||||
cwd,
|
||||
'build2',
|
||||
'oss-experimental',
|
||||
'react',
|
||||
'package.json'
|
||||
);
|
||||
const {version} = await readJson(packageJSON);
|
||||
return extractCommitFromVersionNumber(version);
|
||||
}
|
||||
};
|
||||
|
||||
const getPublicPackages = isExperimental => {
|
||||
if (isExperimental) {
|
||||
return [
|
||||
@@ -270,6 +309,7 @@ module.exports = {
|
||||
getArtifactsList,
|
||||
getBuildInfo,
|
||||
getChecksumForCurrentRevision,
|
||||
getCommitFromCurrentBuild,
|
||||
getPublicPackages,
|
||||
handleError,
|
||||
logPromise,
|
||||
|
||||
Reference in New Issue
Block a user