[DevTools] Make Devtools Regression Build (#24599)
This PR adds a script that downloads the specified react version from NPM (ie. react-dom, react, and react-test-renderer) and replaces the corresponding files in the build folder with the downloaded react files. The scheduler package, unlike react-dom, react, and react-test-renderer, is versioned differently, so we also need to specifically account for that in the script.
Luna Ruan committed
May 23, 2022 at 11:33 UTC
210fee474d7152b08171c2953678b607f8baad3e
1 file changed
+114
scripts/circleci/download_devtools_regression_build.js
new
+114
@@ -0,0 +1,114 @@
1
+#!/usr/bin/env node
2
+
3
+'use strict';
4
+
5
+const {exec} = require('child-process-promise');
6
+const chalk = require('chalk');
7
+const {join} = require('path');
8
+const semver = require('semver');
9
+const fs = require('fs');
10
+
11
+const INSTALL_PACKAGES = ['react-dom', 'react', 'react-test-renderer'];
12
+const REGRESSION_FOLDER = 'build-regression';
13
+
14
+const ROOT_PATH = join(__dirname, '..', '..');
15
+
16
+const buildPath = join(ROOT_PATH, `build`, 'oss-experimental');
17
+const regressionBuildPath = join(ROOT_PATH, REGRESSION_FOLDER);
18
+
19
+const version = process.argv[2];
20
+
21
+async function downloadRegressionBuild() {
22
+ console.log(chalk.bold.white(`Downloading React v${version}\n`));
23
+
24
+ // Make build directory for temporary modules we're going to download
25
+ // from NPM
26
+ console.log(
27
+ chalk.white(
28
+ `Make Build directory at ${chalk.underline.blue(regressionBuildPath)}\n`
29
+ )
30
+ );
31
+ await exec(`mkdir ${regressionBuildPath}`);
32
+
33
+ // Install all necessary React packages that have the same version
34
+ const downloadPackagesStr = INSTALL_PACKAGES.reduce(
35
+ (str, name) => `${str} ${name}@${version}`,
36
+ ''
37
+ );
38
+ await exec(
39
+ `npm install --prefix ${REGRESSION_FOLDER} ${downloadPackagesStr}`
40
+ );
41
+
42
+ // Remove all the packages that we downloaded in the original build folder
43
+ // so we can move the modules from the regression build over
44
+ const removePackagesStr = INSTALL_PACKAGES.reduce(
45
+ (str, name) => `${str} ${join(buildPath, name)}`,
46
+ ''
47
+ );
48
+ console.log(
49
+ chalk.white(
50
+ `Removing ${removePackagesStr
51
+ .split(' ')
52
+ .map(str => chalk.underline.blue(str) + '\n')
53
+ .join(' ')}\n`
54
+ )
55
+ );
56
+ await exec(`rm -r ${removePackagesStr}`);
57
+
58
+ // Move all packages that we downloaded to the original build folder
59
+ // We need to separately move the scheduler package because it might
60
+ // be called schedule
61
+ const movePackageString = INSTALL_PACKAGES.reduce(
62
+ (str, name) => `${str} ${join(regressionBuildPath, 'node_modules', name)}`,
63
+ ''
64
+ );
65
+ console.log(
66
+ chalk.white(
67
+ `Moving ${movePackageString
68
+ .split(' ')
69
+ .map(str => chalk.underline.blue(str) + '\n')
70
+ .join(' ')} to ${chalk.underline.blue(buildPath)}\n`
71
+ )
72
+ );
73
+ await exec(`mv ${movePackageString} ${buildPath}`);
74
+
75
+ // For React versions earlier than 18.0.0, we explicitly scheduler v0.20.1, which
76
+ // is the first version that has unstable_mock, which DevTools tests need, but also
77
+ // has Scheduler.unstable_trace, which, although we don't use in DevTools tests
78
+ // is imported by older React versions and will break if it's not ther
79
+ if (semver.lte(semver.coerce(version).version, '18.0.0')) {
80
+ await exec(`npm install --prefix ${REGRESSION_FOLDER} scheduler@0.20.1`);
81
+ }
82
+
83
+ // In v16.5, scheduler is called schedule. We need to make sure we also move
84
+ // this over. Otherwise the code will break.
85
+ if (fs.existsSync(join(regressionBuildPath, 'node_modules', 'schedule'))) {
86
+ console.log(chalk.white(`Downloading schedule\n`));
87
+ await exec(
88
+ `mv ${join(regressionBuildPath, 'node_modules', 'schedule')} ${buildPath}`
89
+ );
90
+ } else {
91
+ console.log(chalk.white(`Downloading scheduler\n`));
92
+ await exec(`rm -r ${join(buildPath, 'scheduler')}`);
93
+ await exec(
94
+ `mv ${join(
95
+ regressionBuildPath,
96
+ 'node_modules',
97
+ 'scheduler'
98
+ )} ${buildPath}`
99
+ );
100
+ }
101
+}
102
+
103
+async function main() {
104
+ try {
105
+ await downloadRegressionBuild();
106
+ } catch (e) {
107
+ console.log(chalk.red(e));
108
+ } finally {
109
+ console.log(chalk.bold.white(`Removing regression build`));
110
+ await exec(`rm -r ${regressionBuildPath}`);
111
+ }
112
+}
113
+
114
+main();