From 7b483a1823bd152b3abf4f192755d3d45a5773d0 Mon Sep 17 00:00:00 2001 From: Andrew Clark Date: Mon, 3 Jun 2024 11:26:53 -0400 Subject: [PATCH] Update build script to automatically generate RCs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit RC releases are a special kind of prerelease build because unlike canaries we shouldn't publish new RCs from any commit on `main`, only when we intentionally bump the RC number. But they are still prerelases — like canary and experimental releases, they should use exact version numbers in their dependencies (no ^). We only need to generate these builds during the RC phase, i.e. when the canary channel label is set to "rc". --- ReactVersions.js | 5 ++++ .../download-build-artifacts.js | 2 ++ .../release/shared-commands/parse-params.js | 3 +- scripts/rollup/build-all-release-channels.js | 28 +++++++++++++++++++ 4 files changed, 37 insertions(+), 1 deletion(-) diff --git a/ReactVersions.js b/ReactVersions.js index 14e3ba57c4521..8fb7586ec892f 100644 --- a/ReactVersions.js +++ b/ReactVersions.js @@ -28,6 +28,10 @@ const ReactVersion = '19.0.0'; // npm dist tags used during publish, refer to .circleci/config.yml. const canaryChannelLabel = 'rc'; +// If the canaryChannelLabel is "rc", the build pipeline will use this to build +// an RC version of the packages. +const rcNumber = 0; + const stablePackages = { 'eslint-plugin-react-hooks': '5.1.0', 'jest-react': '0.16.0', @@ -53,6 +57,7 @@ const experimentalPackages = []; module.exports = { ReactVersion, canaryChannelLabel, + rcNumber, stablePackages, experimentalPackages, }; diff --git a/scripts/release/shared-commands/download-build-artifacts.js b/scripts/release/shared-commands/download-build-artifacts.js index 2952bc977103c..2539abd6a6294 100644 --- a/scripts/release/shared-commands/download-build-artifacts.js +++ b/scripts/release/shared-commands/download-build-artifacts.js @@ -50,6 +50,8 @@ const run = async ({build, cwd, releaseChannel}) => { sourceDir = 'oss-stable'; } else if (releaseChannel === 'experimental') { sourceDir = 'oss-experimental'; + } else if (releaseChannel === 'rc') { + sourceDir = 'oss-stable-rc'; } else if (releaseChannel === 'latest') { sourceDir = 'oss-stable-semver'; } else { diff --git a/scripts/release/shared-commands/parse-params.js b/scripts/release/shared-commands/parse-params.js index 1866cbb8aafd0..6e3b7837091de 100644 --- a/scripts/release/shared-commands/parse-params.js +++ b/scripts/release/shared-commands/parse-params.js @@ -50,10 +50,11 @@ module.exports = async () => { if ( channel !== 'experimental' && channel !== 'stable' && + channel !== 'rc' && channel !== 'latest' ) { console.error( - theme.error`Invalid release channel (-r) "${channel}". Must be "stable", "experimental", or "latest".` + theme.error`Invalid release channel (-r) "${channel}". Must be "stable", "experimental", "rc", or "latest".` ); process.exit(1); } diff --git a/scripts/rollup/build-all-release-channels.js b/scripts/rollup/build-all-release-channels.js index 13ac464c7baee..76a2d152a9ed2 100644 --- a/scripts/rollup/build-all-release-channels.js +++ b/scripts/rollup/build-all-release-channels.js @@ -13,6 +13,7 @@ const { stablePackages, experimentalPackages, canaryChannelLabel, + rcNumber, } = require('../../ReactVersions'); // Runs the build script for both stable and experimental release channels, @@ -118,6 +119,13 @@ function processStable(buildDir) { // Identical to `oss-stable` but with real, semver versions. This is what // will get published to @latest. shell.cp('-r', buildDir + '/node_modules', buildDir + '/oss-stable-semver'); + if (canaryChannelLabel === 'rc') { + // During the RC phase, we also generate an RC build that pins to exact + // versions but does not include a SHA, e.g. `19.0.0-rc.0`. This is purely + // for signaling purposes — aside from the version, it's no different from + // the corresponding canary. + shell.cp('-r', buildDir + '/node_modules', buildDir + '/oss-stable-rc'); + } const defaultVersionIfNotFound = '0.0.0' + '-' + sha + '-' + dateString; const versionsMap = new Map(); @@ -141,6 +149,25 @@ function processStable(buildDir) { ReactVersion + '-' + canaryChannelLabel + '-' + sha + '-' + dateString ); + if (canaryChannelLabel === 'rc') { + const rcVersionsMap = new Map(); + for (const moduleName in stablePackages) { + const version = stablePackages[moduleName]; + rcVersionsMap.set(moduleName, version + `-rc.${rcNumber}`); + } + updatePackageVersions( + buildDir + '/oss-stable-rc', + rcVersionsMap, + defaultVersionIfNotFound, + // For RCs, we pin to exact versions, like we do for canaries. + true + ); + updatePlaceholderReactVersionInCompiledArtifacts( + buildDir + '/oss-stable-rc', + ReactVersion + ); + } + // Now do the semver ones const semverVersionsMap = new Map(); for (const moduleName in stablePackages) { @@ -151,6 +178,7 @@ function processStable(buildDir) { buildDir + '/oss-stable-semver', semverVersionsMap, defaultVersionIfNotFound, + // Use ^ only for non-prerelease versions false ); updatePlaceholderReactVersionInCompiledArtifacts(