From f8b6969da65457cd18b434616cb01ac1c7b0afcc Mon Sep 17 00:00:00 2001 From: Andrew Clark Date: Mon, 1 Feb 2021 10:27:59 -0600 Subject: [PATCH] Add `--commit` param to release scripts (#20703) Alternative to `--build`. Uses same logic as sizebot and www sync script. Immediate motivation is I want sizebot to use the `download-experimental-build` command in CI. Will do that next. --- .../release/download-experimental-build.js | 2 +- scripts/release/get-build-id-for-commit.js | 34 +++++++++++++++++++ scripts/release/prepare-release-from-ci.js | 2 +- .../release/shared-commands/parse-params.js | 31 ++++++++++++++++- 4 files changed, 66 insertions(+), 3 deletions(-) create mode 100644 scripts/release/get-build-id-for-commit.js diff --git a/scripts/release/download-experimental-build.js b/scripts/release/download-experimental-build.js index 75080554c9d94..ae5e69857990b 100755 --- a/scripts/release/download-experimental-build.js +++ b/scripts/release/download-experimental-build.js @@ -19,7 +19,7 @@ const run = async () => { try { addDefaultParamValue('-r', '--releaseChannel', 'experimental'); - const params = parseParams(); + const params = await parseParams(); params.cwd = join(__dirname, '..', '..'); params.packages = await getPublicPackages(true); diff --git a/scripts/release/get-build-id-for-commit.js b/scripts/release/get-build-id-for-commit.js new file mode 100644 index 0000000000000..88350e99d280d --- /dev/null +++ b/scripts/release/get-build-id-for-commit.js @@ -0,0 +1,34 @@ +'use strict'; + +const fetch = require('node-fetch'); + +async function getBuildIdForCommit(sha) { + let ciBuildId = null; + const statusesResponse = await fetch( + `https://api.github.com/repos/facebook/react/commits/${sha}/status` + ); + + if (!statusesResponse.ok) { + throw Error('Could not find commit for: ' + sha); + } + + const {statuses, state} = await statusesResponse.json(); + if (state === 'failure') { + throw new Error(`Base commit is broken: ${sha}`); + } + for (let i = 0; i < statuses.length; i++) { + const status = statuses[i]; + if (status.context === `ci/circleci: process_artifacts_combined`) { + if (status.state === 'success') { + ciBuildId = /\/facebook\/react\/([0-9]+)/.exec(status.target_url)[1]; + break; + } + if (status.state === 'pending') { + throw new Error(`Build job for base commit is still pending: ${sha}`); + } + } + } + return ciBuildId; +} + +module.exports = getBuildIdForCommit; diff --git a/scripts/release/prepare-release-from-ci.js b/scripts/release/prepare-release-from-ci.js index dd8e143453f79..12b0b76409a7d 100755 --- a/scripts/release/prepare-release-from-ci.js +++ b/scripts/release/prepare-release-from-ci.js @@ -15,7 +15,7 @@ const testTracingFixture = require('./shared-commands/test-tracing-fixture'); const run = async () => { try { - const params = parseParams(); + const params = await parseParams(); params.cwd = join(__dirname, '..', '..'); if (!params.build) { diff --git a/scripts/release/shared-commands/parse-params.js b/scripts/release/shared-commands/parse-params.js index 2ec21020282fa..5755a8ee65879 100644 --- a/scripts/release/shared-commands/parse-params.js +++ b/scripts/release/shared-commands/parse-params.js @@ -3,6 +3,7 @@ 'use strict'; const commandLineArgs = require('command-line-args'); +const getBuildIdForCommit = require('../get-build-id-for-commit'); const paramDefinitions = [ { @@ -10,6 +11,14 @@ const paramDefinitions = [ type: Number, description: 'Circle CI build identifier (e.g. https://circleci.com/gh/facebook/react/)', + defaultValue: null, + }, + { + name: 'commit', + type: String, + description: + 'GitHub commit SHA. When provided, automatically finds corresponding CI build.', + defaultValue: null, }, { name: 'skipTests', @@ -25,9 +34,29 @@ const paramDefinitions = [ }, ]; -module.exports = () => { +module.exports = async () => { const params = commandLineArgs(paramDefinitions); + if (params.build !== null) { + if (params.commit !== null) { + console.error( + '`build` and `commmit` params are mutually exclusive. Choose one or the other.`' + ); + process.exit(1); + } + } 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(