Skip to content

Commit bf3a29d

Browse files
authored
Update build script to automatically generate RCs (#29736)
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". Example of resulting package.json output: ```json { "name": "react-dom", "version": "19.0.0-rc.0", "dependencies": { "scheduler": "0.25.0-rc.0" }, "peerDependencies": { "react": "19.0.0-rc.0" } } ``` https://react-builds.vercel.app/prs/29736/files/oss-stable-rc/react-dom/package.json
1 parent 9598c41 commit bf3a29d

File tree

4 files changed

+37
-1
lines changed

4 files changed

+37
-1
lines changed

ReactVersions.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@ const ReactVersion = '19.0.0';
2828
// npm dist tags used during publish, refer to .circleci/config.yml.
2929
const canaryChannelLabel = 'rc';
3030

31+
// If the canaryChannelLabel is "rc", the build pipeline will use this to build
32+
// an RC version of the packages.
33+
const rcNumber = 0;
34+
3135
const stablePackages = {
3236
'eslint-plugin-react-hooks': '5.1.0',
3337
'jest-react': '0.16.0',
@@ -53,6 +57,7 @@ const experimentalPackages = [];
5357
module.exports = {
5458
ReactVersion,
5559
canaryChannelLabel,
60+
rcNumber,
5661
stablePackages,
5762
experimentalPackages,
5863
};

scripts/release/shared-commands/download-build-artifacts.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ const run = async ({build, cwd, releaseChannel}) => {
5050
sourceDir = 'oss-stable';
5151
} else if (releaseChannel === 'experimental') {
5252
sourceDir = 'oss-experimental';
53+
} else if (releaseChannel === 'rc') {
54+
sourceDir = 'oss-stable-rc';
5355
} else if (releaseChannel === 'latest') {
5456
sourceDir = 'oss-stable-semver';
5557
} else {

scripts/release/shared-commands/parse-params.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,11 @@ module.exports = async () => {
5050
if (
5151
channel !== 'experimental' &&
5252
channel !== 'stable' &&
53+
channel !== 'rc' &&
5354
channel !== 'latest'
5455
) {
5556
console.error(
56-
theme.error`Invalid release channel (-r) "${channel}". Must be "stable", "experimental", or "latest".`
57+
theme.error`Invalid release channel (-r) "${channel}". Must be "stable", "experimental", "rc", or "latest".`
5758
);
5859
process.exit(1);
5960
}

scripts/rollup/build-all-release-channels.js

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ const {
1313
stablePackages,
1414
experimentalPackages,
1515
canaryChannelLabel,
16+
rcNumber,
1617
} = require('../../ReactVersions');
1718

1819
// Runs the build script for both stable and experimental release channels,
@@ -118,6 +119,13 @@ function processStable(buildDir) {
118119
// Identical to `oss-stable` but with real, semver versions. This is what
119120
// will get published to @latest.
120121
shell.cp('-r', buildDir + '/node_modules', buildDir + '/oss-stable-semver');
122+
if (canaryChannelLabel === 'rc') {
123+
// During the RC phase, we also generate an RC build that pins to exact
124+
// versions but does not include a SHA, e.g. `19.0.0-rc.0`. This is purely
125+
// for signaling purposes — aside from the version, it's no different from
126+
// the corresponding canary.
127+
shell.cp('-r', buildDir + '/node_modules', buildDir + '/oss-stable-rc');
128+
}
121129

122130
const defaultVersionIfNotFound = '0.0.0' + '-' + sha + '-' + dateString;
123131
const versionsMap = new Map();
@@ -141,6 +149,25 @@ function processStable(buildDir) {
141149
ReactVersion + '-' + canaryChannelLabel + '-' + sha + '-' + dateString
142150
);
143151

152+
if (canaryChannelLabel === 'rc') {
153+
const rcVersionsMap = new Map();
154+
for (const moduleName in stablePackages) {
155+
const version = stablePackages[moduleName];
156+
rcVersionsMap.set(moduleName, version + `-rc.${rcNumber}`);
157+
}
158+
updatePackageVersions(
159+
buildDir + '/oss-stable-rc',
160+
rcVersionsMap,
161+
defaultVersionIfNotFound,
162+
// For RCs, we pin to exact versions, like we do for canaries.
163+
true
164+
);
165+
updatePlaceholderReactVersionInCompiledArtifacts(
166+
buildDir + '/oss-stable-rc',
167+
ReactVersion
168+
);
169+
}
170+
144171
// Now do the semver ones
145172
const semverVersionsMap = new Map();
146173
for (const moduleName in stablePackages) {
@@ -151,6 +178,7 @@ function processStable(buildDir) {
151178
buildDir + '/oss-stable-semver',
152179
semverVersionsMap,
153180
defaultVersionIfNotFound,
181+
// Use ^ only for non-prerelease versions
154182
false
155183
);
156184
updatePlaceholderReactVersionInCompiledArtifacts(

0 commit comments

Comments
 (0)