Skip to content

Commit 36ac253

Browse files
committed
Update package.json versions as part of build step
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 36ac253

File tree

1 file changed

+66
-6
lines changed

1 file changed

+66
-6
lines changed

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)