Skip to content

Commit e6ed2bc

Browse files
authored
Update package.json versions as part of build step (#20579)
Fixes issue in the new build workflow where the experimental packages do not include "experimental" in the version string. This was because the previous approach relied on the RELEASE_CHANNEL environment variable, which we are no longer setting in the outer CI job, since we use the same job to build both channels. To solve, I moved the version post-processing into the build script itself. Only affects the new build workflow. Old workflow is unchanged. Longer term, I would like to remove version numbers from the source entirely, including the package.jsons. We should use a placeholder instead; that's mostly how it already works, since the release script swaps out the versions before we publish to stable.
1 parent b99ac3d commit e6ed2bc

File tree

2 files changed

+67
-11
lines changed

2 files changed

+67
-11
lines changed

.circleci/config.yml

+1-5
Original file line numberDiff line numberDiff line change
@@ -168,11 +168,7 @@ jobs:
168168
- checkout
169169
- run: yarn workspaces info | head -n -1 > workspace_info.txt
170170
- *restore_node_modules
171-
- run:
172-
command: |
173-
./scripts/circleci/add_build_info_json.sh
174-
./scripts/circleci/update_package_versions.sh
175-
yarn build-combined
171+
- run: yarn build-combined
176172
- persist_to_workspace:
177173
root: build2
178174
paths:

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

+66-6
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,18 @@
44

55
const fs = require('fs');
66
const {spawnSync} = require('child_process');
7+
const path = require('path');
78
const tmp = require('tmp');
89

910
// Runs the build script for both stable and experimental release channels,
1011
// by configuring an environment variable.
1112

13+
const sha = (
14+
spawnSync('git', ['show', '-s', '--format=%h']).stdout + ''
15+
).trim();
16+
const ReactVersion = JSON.parse(fs.readFileSync('packages/react/package.json'))
17+
.version;
18+
1219
if (process.env.CIRCLE_NODE_TOTAL) {
1320
// In CI, we use multiple concurrent processes. Allocate half the processes to
1421
// build the stable channel, and the other half for experimental. Override
@@ -19,13 +26,19 @@ if (process.env.CIRCLE_NODE_TOTAL) {
1926
if (index < halfTotal) {
2027
const nodeTotal = halfTotal;
2128
const nodeIndex = index;
29+
const version = '0.0.0-' + sha;
30+
updateTheReactVersionThatDevToolsReads(ReactVersion + '-' + sha);
2231
buildForChannel('stable', nodeTotal, nodeIndex);
23-
processStable('./build');
32+
processStable('./build', version);
2433
} else {
2534
const nodeTotal = total - halfTotal;
2635
const nodeIndex = index - halfTotal;
36+
const version = '0.0.0-experimental-' + sha;
37+
updateTheReactVersionThatDevToolsReads(
38+
ReactVersion + '-experimental-' + sha
39+
);
2740
buildForChannel('experimental', nodeTotal, nodeIndex);
28-
processExperimental('./build');
41+
processExperimental('./build', version);
2942
}
3043

3144
// TODO: Currently storing artifacts as `./build2` so that it doesn't conflict
@@ -34,15 +47,17 @@ if (process.env.CIRCLE_NODE_TOTAL) {
3447
} else {
3548
// Running locally, no concurrency. Move each channel's build artifacts into
3649
// a temporary directory so that they don't conflict.
50+
const stableVersion = '0.0.0-' + sha;
3751
buildForChannel('stable', '', '');
3852
const stableDir = tmp.dirSync().name;
3953
fs.renameSync('./build', stableDir);
40-
processStable(stableDir);
54+
processStable(stableDir, stableVersion);
4155

56+
const experimentalVersion = '0.0.0-experimental-' + sha;
4257
buildForChannel('experimental', '', '');
4358
const experimentalDir = tmp.dirSync().name;
4459
fs.renameSync('./build', experimentalDir);
45-
processExperimental(experimentalDir);
60+
processExperimental(experimentalDir, experimentalVersion);
4661

4762
// Then merge the experimental folder into the stable one. processExperimental
4863
// will have already removed conflicting files.
@@ -68,8 +83,9 @@ function buildForChannel(channel, nodeTotal, nodeIndex) {
6883
});
6984
}
7085

71-
function processStable(buildDir) {
86+
function processStable(buildDir, version) {
7287
if (fs.existsSync(buildDir + '/node_modules')) {
88+
updatePackageVersions(buildDir + '/node_modules', version);
7389
fs.renameSync(buildDir + '/node_modules', buildDir + '/oss-stable');
7490
}
7591

@@ -88,8 +104,9 @@ function processStable(buildDir) {
88104
}
89105
}
90106

91-
function processExperimental(buildDir) {
107+
function processExperimental(buildDir, version) {
92108
if (fs.existsSync(buildDir + '/node_modules')) {
109+
updatePackageVersions(buildDir + '/node_modules', version);
93110
fs.renameSync(buildDir + '/node_modules', buildDir + '/oss-experimental');
94111
}
95112

@@ -121,3 +138,46 @@ function processExperimental(buildDir) {
121138
}
122139
}
123140
}
141+
142+
function updatePackageVersions(modulesDir, version) {
143+
const allReactModuleNames = fs.readdirSync('packages');
144+
for (const moduleName of fs.readdirSync(modulesDir)) {
145+
const packageJSONPath = path.join(modulesDir, moduleName, 'package.json');
146+
const stats = fs.statSync(packageJSONPath);
147+
if (stats.isFile()) {
148+
const packageInfo = JSON.parse(fs.readFileSync(packageJSONPath));
149+
150+
// Update version
151+
packageInfo.version = version;
152+
153+
// Update dependency versions
154+
if (packageInfo.dependencies) {
155+
for (const dep of Object.keys(packageInfo.dependencies)) {
156+
if (allReactModuleNames.includes(dep)) {
157+
packageInfo.dependencies[dep] = version;
158+
}
159+
}
160+
}
161+
if (packageInfo.peerDependencies) {
162+
for (const dep of Object.keys(packageInfo.peerDependencies)) {
163+
if (allReactModuleNames.includes(dep)) {
164+
packageInfo.peerDependencies[dep] = version;
165+
}
166+
}
167+
}
168+
169+
// Write out updated package.json
170+
fs.writeFileSync(packageJSONPath, JSON.stringify(packageInfo, null, 2));
171+
}
172+
}
173+
}
174+
175+
function updateTheReactVersionThatDevToolsReads(version) {
176+
// Overwrite the ReactVersion module before the build script runs so that it
177+
// is included in the final bundles. This only runs in CI, so it's fine to
178+
// edit the source file.
179+
fs.writeFileSync(
180+
'./packages/shared/ReactVersion.js',
181+
`export default '${version}';\n`
182+
);
183+
}

0 commit comments

Comments
 (0)