main
js 122 lines 3.44 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 {readJsonSync} = require('fs-extra');
8 const inquirer = require('inquirer');
9 const {join, relative} = require('path');
10 const {DRY_RUN, NPM_PACKAGES, ROOT_PATH} = require('./configuration');
11 const {
12 checkNPMPermissions,
13 clear,
14 confirm,
15 execRead,
16 logger,
17 readSavedBuildMetadata,
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 run the build-and-test script?', () => {
25 const buildAndTestScriptPath = join(__dirname, 'build-and-test.js');
26 const pathToPrint = relative(process.cwd(), buildAndTestScriptPath);
27
28 console.log('Begin by running the build-and-test script:');
29 console.log(chalk.bold.green(' ' + pathToPrint));
30 });
31
32 const {archivePath, currentCommitHash} = readSavedBuildMetadata();
33
34 await checkNPMPermissions();
35
36 await publishToNPM();
37
38 await printFinalInstructions(currentCommitHash, archivePath);
39 }
40
41 async function printFinalInstructions(currentCommitHash, archivePath) {
42 console.log('');
43 console.log(
44 'You are now ready to publish the extension to Chrome, Edge, and Firefox:'
45 );
46 console.log(
47 ` ${chalk.blue.underline(
48 'https://fburl.com/publish-react-devtools-extensions'
49 )}`
50 );
51 console.log('');
52 console.log('When publishing to Firefox, remember the following:');
53 console.log(` Commit Hash: ${chalk.bold(currentCommitHash)}`);
54 console.log(` Git archive: ${chalk.bold(archivePath)}`);
55 console.log('');
56 console.log('Also consider syncing this release to Facebook:');
57 console.log(` ${chalk.bold.green('js1 upgrade react-devtools')}`);
58 }
59
60 async function publishToNPM() {
61 const {otp} = await inquirer.prompt([
62 {
63 type: 'input',
64 name: 'otp',
65 message: 'Please provide an NPM two-factor auth token:',
66 },
67 ]);
68
69 console.log('');
70
71 if (!otp) {
72 console.error(chalk.red(`Invalid OTP provided: "${chalk.bold(otp)}"`));
73 process.exit(0);
74 }
75
76 for (let index = 0; index < NPM_PACKAGES.length; index++) {
77 const npmPackage = NPM_PACKAGES[index];
78 const packagePath = join(ROOT_PATH, 'packages', npmPackage);
79 const {version} = readJsonSync(join(packagePath, 'package.json'));
80
81 // Check if this package version has already been published.
82 // If so we might be resuming from a previous run.
83 // We could infer this by comparing the build-info.json,
84 // But for now the easiest way is just to ask if this is expected.
85 const versionListJSON = await execRead(
86 `npm view ${npmPackage} versions --json`
87 );
88 const versionList = JSON.parse(versionListJSON);
89 const versionIsAlreadyPublished = versionList.includes(version);
90
91 if (versionIsAlreadyPublished) {
92 console.log('');
93 console.log(
94 `${npmPackage} version ${chalk.bold(
95 version
96 )} has already been published.`
97 );
98
99 await confirm(`Is this expected (will skip ${npmPackage}@${version})?`);
100 continue;
101 }
102
103 if (DRY_RUN) {
104 console.log(`Publishing package ${chalk.bold(npmPackage)}`);
105 console.log(chalk.dim(` npm publish --otp=${otp}`));
106 } else {
107 const publishPromise = exec(`npm publish --otp=${otp}`, {
108 cwd: packagePath,
109 });
110
111 await logger(
112 publishPromise,
113 `Publishing package ${chalk.bold(npmPackage)}`,
114 {
115 estimate: 2500,
116 }
117 );
118 }
119 }
120 }
121
122 main();