main
js 239 lines 6.59 KB
Raw
1 #!/usr/bin/env node
2
3 'use strict';
4
5 const chalk = require('chalk');
6 const {exec} = require('child-process-promise');
7 const inquirer = require('inquirer');
8 const {homedir} = require('os');
9 const {join, relative} = require('path');
10 const {DRY_RUN, ROOT_PATH} = require('./configuration');
11 const {
12 clear,
13 confirm,
14 confirmContinue,
15 execRead,
16 logger,
17 saveBuildMetadata,
18 } = require('./utils');
19
20 // This is the primary control function for this script.
21 async function main() {
22 clear();
23
24 await confirm('Have you stopped all NPM DEV scripts?', () => {
25 const packagesPath = relative(process.cwd(), join(__dirname, 'packages'));
26
27 console.log('Stop all NPM DEV scripts in the following directories:');
28 console.log(
29 chalk.bold(' ' + join(packagesPath, 'react-devtools-core')),
30 chalk.gray('(start:backend, start:standalone)')
31 );
32 console.log(
33 chalk.bold(' ' + join(packagesPath, 'react-devtools-inline')),
34 chalk.gray('(start)')
35 );
36
37 const buildAndTestScriptPath = join(__dirname, 'build-and-test.js');
38 const pathToPrint = relative(process.cwd(), buildAndTestScriptPath);
39
40 console.log('\nThen restart this release step:');
41 console.log(chalk.bold.green(' ' + pathToPrint));
42 });
43
44 await confirm('Have you run the prepare-release script?', () => {
45 const prepareReleaseScriptPath = join(__dirname, 'prepare-release.js');
46 const pathToPrint = relative(process.cwd(), prepareReleaseScriptPath);
47
48 console.log('Begin by running the prepare-release script:');
49 console.log(chalk.bold.green(' ' + pathToPrint));
50 });
51
52 const archivePath = await archiveGitRevision();
53 const currentCommitHash = await downloadLatestReactBuild();
54
55 await buildAndTestInlinePackage();
56 await buildAndTestStandalonePackage();
57 await buildAndTestExtensions();
58
59 saveBuildMetadata({archivePath, currentCommitHash});
60
61 printFinalInstructions();
62 }
63
64 async function archiveGitRevision() {
65 const desktopPath = join(homedir(), 'Desktop');
66 const archivePath = join(desktopPath, 'DevTools.tgz');
67
68 console.log(`Creating git archive at ${chalk.dim(archivePath)}`);
69 console.log('');
70
71 if (!DRY_RUN) {
72 await exec(`git archive main | gzip > ${archivePath}`, {cwd: ROOT_PATH});
73 }
74
75 return archivePath;
76 }
77
78 async function buildAndTestExtensions() {
79 const extensionsPackagePath = join(
80 ROOT_PATH,
81 'packages',
82 'react-devtools-extensions'
83 );
84 const buildExtensionsPromise = exec('yarn build', {
85 cwd: extensionsPackagePath,
86 });
87
88 await logger(
89 buildExtensionsPromise,
90 `Building browser extensions ${chalk.dim('(this may take a minute)')}`,
91 {
92 estimate: 60000,
93 }
94 );
95
96 console.log('');
97 console.log(`Extensions have been build for Chrome, Edge, and Firefox.`);
98 console.log('');
99 console.log('Smoke test each extension before continuing:');
100 console.log(` ${chalk.bold.green('cd ' + extensionsPackagePath)}`);
101 console.log('');
102 console.log(` ${chalk.dim('# Test Chrome extension')}`);
103 console.log(` ${chalk.bold.green('yarn test:chrome')}`);
104 console.log('');
105 console.log(` ${chalk.dim('# Test Edge extension')}`);
106 console.log(` ${chalk.bold.green('yarn test:edge')}`);
107 console.log('');
108 console.log(` ${chalk.dim('# Firefox Chrome extension')}`);
109 console.log(` ${chalk.bold.green('yarn test:firefox')}`);
110
111 await confirmContinue();
112 }
113
114 async function buildAndTestStandalonePackage() {
115 const corePackagePath = join(ROOT_PATH, 'packages', 'react-devtools-core');
116 const corePackageDest = join(corePackagePath, 'dist');
117
118 await exec(`rm -rf ${corePackageDest}`);
119 const buildCorePromise = exec('yarn build', {cwd: corePackagePath});
120
121 await logger(
122 buildCorePromise,
123 `Building ${chalk.bold('react-devtools-core')} package.`,
124 {
125 estimate: 25000,
126 }
127 );
128
129 const standalonePackagePath = join(ROOT_PATH, 'packages', 'react-devtools');
130 const safariFixturePath = join(
131 ROOT_PATH,
132 'fixtures',
133 'devtools',
134 'standalone',
135 'index.html'
136 );
137
138 console.log('');
139 console.log(
140 `Test the ${chalk.bold('react-devtools-core')} target before continuing:`
141 );
142 console.log(` ${chalk.bold.green('cd ' + standalonePackagePath)}`);
143 console.log(` ${chalk.bold.green('yarn start')}`);
144 console.log('');
145 console.log(
146 'The following fixture can be useful for testing Safari integration:'
147 );
148 console.log(` ${chalk.dim(safariFixturePath)}`);
149
150 await confirmContinue();
151 }
152
153 async function buildAndTestInlinePackage() {
154 const inlinePackagePath = join(
155 ROOT_PATH,
156 'packages',
157 'react-devtools-inline'
158 );
159 const inlinePackageDest = join(inlinePackagePath, 'dist');
160
161 await exec(`rm -rf ${inlinePackageDest}`);
162 const buildPromise = exec('yarn build', {cwd: inlinePackagePath});
163
164 await logger(
165 buildPromise,
166 `Building ${chalk.bold('react-devtools-inline')} package.`,
167 {
168 estimate: 10000,
169 }
170 );
171
172 const shellPackagePath = join(ROOT_PATH, 'packages', 'react-devtools-shell');
173
174 console.log('');
175 console.log(`Built ${chalk.bold('react-devtools-inline')} target.`);
176 console.log('');
177 console.log('Test this build before continuing:');
178 console.log(` ${chalk.bold.green('cd ' + shellPackagePath)}`);
179 console.log(` ${chalk.bold.green('yarn start')}`);
180
181 await confirmContinue();
182 }
183
184 async function downloadLatestReactBuild() {
185 const releaseScriptPath = join(ROOT_PATH, 'scripts', 'release');
186 const installPromise = exec('yarn install', {cwd: releaseScriptPath});
187
188 await logger(
189 installPromise,
190 `Installing release script dependencies. ${chalk.dim(
191 '(this may take a minute if CI is still running)'
192 )}`,
193 {
194 estimate: 5000,
195 }
196 );
197
198 console.log('');
199
200 const currentCommitHash = (await exec('git rev-parse HEAD')).stdout.trim();
201 if (!currentCommitHash) {
202 throw new Error('Failed to get current commit hash');
203 }
204
205 const {commit} = await inquirer.prompt([
206 {
207 type: 'input',
208 name: 'commit',
209 message: 'Which React version (commit) should be used?',
210 default: currentCommitHash,
211 },
212 ]);
213 console.log('');
214
215 const downloadScriptPath = join(
216 releaseScriptPath,
217 'download-experimental-build.js'
218 );
219 const downloadPromise = execRead(
220 `"${downloadScriptPath}" --commit=${commit}`
221 );
222
223 await logger(downloadPromise, 'Downloading React artifacts from CI.', {
224 estimate: 15000,
225 });
226
227 return currentCommitHash;
228 }
229
230 function printFinalInstructions() {
231 const publishReleaseScriptPath = join(__dirname, 'publish-release.js');
232 const pathToPrint = relative(process.cwd(), publishReleaseScriptPath);
233
234 console.log('');
235 console.log('Continue by running the publish-release script:');
236 console.log(chalk.bold.green(' ' + pathToPrint));
237 }
238
239 main();