From 33ef48fde1c924ac8b8901dd830600ad68ccb105 Mon Sep 17 00:00:00 2001 From: Andrew Clark Date: Wed, 13 Jan 2021 01:10:02 -0600 Subject: [PATCH] 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. --- .circleci/config.yml | 6 +- scripts/rollup/build-all-release-channels.js | 72 ++++++++++++++++++-- 2 files changed, 67 insertions(+), 11 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index c413bae823ceb..b5f7604059020 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -168,11 +168,7 @@ jobs: - checkout - run: yarn workspaces info | head -n -1 > workspace_info.txt - *restore_node_modules - - run: - command: | - ./scripts/circleci/add_build_info_json.sh - ./scripts/circleci/update_package_versions.sh - yarn build-combined + - run: yarn build-combined - persist_to_workspace: root: build2 paths: diff --git a/scripts/rollup/build-all-release-channels.js b/scripts/rollup/build-all-release-channels.js index 774f1011aa287..0b74e4c42d8e9 100644 --- a/scripts/rollup/build-all-release-channels.js +++ b/scripts/rollup/build-all-release-channels.js @@ -4,11 +4,18 @@ const fs = require('fs'); const {spawnSync} = require('child_process'); +const path = require('path'); const tmp = require('tmp'); // Runs the build script for both stable and experimental release channels, // by configuring an environment variable. +const sha = ( + spawnSync('git', ['show', '-s', '--format=%h']).stdout + '' +).trim(); +const ReactVersion = JSON.parse(fs.readFileSync('packages/react/package.json')) + .version; + if (process.env.CIRCLE_NODE_TOTAL) { // In CI, we use multiple concurrent processes. Allocate half the processes to // build the stable channel, and the other half for experimental. Override @@ -19,13 +26,19 @@ if (process.env.CIRCLE_NODE_TOTAL) { if (index < halfTotal) { const nodeTotal = halfTotal; const nodeIndex = index; + const version = '0.0.0-' + sha; + updateTheReactVersionThatDevToolsReads(ReactVersion + '-' + sha); buildForChannel('stable', nodeTotal, nodeIndex); - processStable('./build'); + processStable('./build', version); } else { const nodeTotal = total - halfTotal; const nodeIndex = index - halfTotal; + const version = '0.0.0-experimental-' + sha; + updateTheReactVersionThatDevToolsReads( + ReactVersion + '-experimental-' + sha + ); buildForChannel('experimental', nodeTotal, nodeIndex); - processExperimental('./build'); + processExperimental('./build', version); } // TODO: Currently storing artifacts as `./build2` so that it doesn't conflict @@ -34,15 +47,17 @@ if (process.env.CIRCLE_NODE_TOTAL) { } else { // Running locally, no concurrency. Move each channel's build artifacts into // a temporary directory so that they don't conflict. + const stableVersion = '0.0.0-' + sha; buildForChannel('stable', '', ''); const stableDir = tmp.dirSync().name; fs.renameSync('./build', stableDir); - processStable(stableDir); + processStable(stableDir, stableVersion); + const experimentalVersion = '0.0.0-experimental-' + sha; buildForChannel('experimental', '', ''); const experimentalDir = tmp.dirSync().name; fs.renameSync('./build', experimentalDir); - processExperimental(experimentalDir); + processExperimental(experimentalDir, experimentalVersion); // Then merge the experimental folder into the stable one. processExperimental // will have already removed conflicting files. @@ -68,8 +83,9 @@ function buildForChannel(channel, nodeTotal, nodeIndex) { }); } -function processStable(buildDir) { +function processStable(buildDir, version) { if (fs.existsSync(buildDir + '/node_modules')) { + updatePackageVersions(buildDir + '/node_modules', version); fs.renameSync(buildDir + '/node_modules', buildDir + '/oss-stable'); } @@ -88,8 +104,9 @@ function processStable(buildDir) { } } -function processExperimental(buildDir) { +function processExperimental(buildDir, version) { if (fs.existsSync(buildDir + '/node_modules')) { + updatePackageVersions(buildDir + '/node_modules', version); fs.renameSync(buildDir + '/node_modules', buildDir + '/oss-experimental'); } @@ -121,3 +138,46 @@ function processExperimental(buildDir) { } } } + +function updatePackageVersions(modulesDir, version) { + const allReactModuleNames = fs.readdirSync('packages'); + for (const moduleName of fs.readdirSync(modulesDir)) { + const packageJSONPath = path.join(modulesDir, moduleName, 'package.json'); + const stats = fs.statSync(packageJSONPath); + if (stats.isFile()) { + const packageInfo = JSON.parse(fs.readFileSync(packageJSONPath)); + + // Update version + packageInfo.version = version; + + // Update dependency versions + if (packageInfo.dependencies) { + for (const dep of Object.keys(packageInfo.dependencies)) { + if (allReactModuleNames.includes(dep)) { + packageInfo.dependencies[dep] = version; + } + } + } + if (packageInfo.peerDependencies) { + for (const dep of Object.keys(packageInfo.peerDependencies)) { + if (allReactModuleNames.includes(dep)) { + packageInfo.peerDependencies[dep] = version; + } + } + } + + // Write out updated package.json + fs.writeFileSync(packageJSONPath, JSON.stringify(packageInfo, null, 2)); + } + } +} + +function updateTheReactVersionThatDevToolsReads(version) { + // Overwrite the ReactVersion module before the build script runs so that it + // is included in the final bundles. This only runs in CI, so it's fine to + // edit the source file. + fs.writeFileSync( + './packages/shared/ReactVersion.js', + `export default '${version}';\n` + ); +}