From 0a47d89963d2940df1e139dc5a973462ed09aee2 Mon Sep 17 00:00:00 2001 From: fabioberger Date: Tue, 23 Jul 2019 15:40:21 +0200 Subject: [PATCH 1/4] Use spawn instead of exec so we can bubble up the OTP prompt since OTP is only valid for 30sec, and we might need several --- packages/monorepo-scripts/src/publish.ts | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/packages/monorepo-scripts/src/publish.ts b/packages/monorepo-scripts/src/publish.ts index a2eedc7d3a..05cba7e101 100644 --- a/packages/monorepo-scripts/src/publish.ts +++ b/packages/monorepo-scripts/src/publish.ts @@ -264,10 +264,25 @@ async function lernaPublishAsync(packageToNextVersion: { [name: string]: string lernaPublishCmd += ` --no-git-tag-version --no-push`; } utils.log('Lerna is publishing...'); - await execAsync(lernaPublishCmd, { + const child = await spawnAsync(lernaPublishCmd, { cwd: constants.monorepoRootPath, maxBuffer: 102400000, // 500 * 1024 * 200 }); + child.stdout.on('data', async (data: Buffer) => { + const output = data.toString('utf8'); + utils.log('Lerna publish cmd: ', output); + const isOTPPrompt = _.includes(output, 'Enter OTP:'); + if (isOTPPrompt) { + // Prompt for OTP + prompt.start(); + const result = await promisify(prompt.get)(['OTP']); + child.stdin.write(`${result.OTP}\n`); + } + }); + child.stderr.on('data', (data: Buffer) => { + const output = data.toString('utf8'); + utils.log('Lerna publish cmd: ', output); + }); } function updateVersionNumberIfNeeded(currentVersion: string, proposedNextVersion: string): string { From cd2d756717227da03e08f256d086bc13492eff02 Mon Sep 17 00:00:00 2001 From: fabioberger Date: Wed, 24 Jul 2019 17:03:06 +0200 Subject: [PATCH 2/4] Use spawn instead of exec so we can intercept any 2FA requests and bubble them to the user --- packages/monorepo-scripts/src/publish.ts | 76 +++++++++++++++--------- 1 file changed, 49 insertions(+), 27 deletions(-) diff --git a/packages/monorepo-scripts/src/publish.ts b/packages/monorepo-scripts/src/publish.ts index 05cba7e101..1cfe3a6414 100644 --- a/packages/monorepo-scripts/src/publish.ts +++ b/packages/monorepo-scripts/src/publish.ts @@ -2,10 +2,13 @@ import { PackageJSON } from '@0x/types'; import { logUtils } from '@0x/utils'; +import { spawn } from 'child_process'; import * as promisify from 'es6-promisify'; +import * as fs from 'fs'; import * as _ from 'lodash'; import * as moment from 'moment'; import opn = require('opn'); +import * as path from 'path'; import { exec as execAsync, spawn as spawnAsync } from 'promisify-child-process'; import * as prompt from 'prompt'; import semver = require('semver'); @@ -254,34 +257,53 @@ async function updateChangeLogsAsync(updatedPublicPackages: Package[]): Promise< } async function lernaPublishAsync(packageToNextVersion: { [name: string]: string }): Promise { - const packageVersionString = _.map(packageToNextVersion, (nextVersion: string, packageName: string) => { - return `${packageName}@${nextVersion}`; - }).join(','); - let lernaPublishCmd = `node ${constants.lernaExecutable} publish --cdVersions=${packageVersionString} --registry=${ - configs.NPM_REGISTRY_URL - } --yes`; - if (configs.IS_LOCAL_PUBLISH) { - lernaPublishCmd += ` --no-git-tag-version --no-push`; - } - utils.log('Lerna is publishing...'); - const child = await spawnAsync(lernaPublishCmd, { - cwd: constants.monorepoRootPath, - maxBuffer: 102400000, // 500 * 1024 * 200 - }); - child.stdout.on('data', async (data: Buffer) => { - const output = data.toString('utf8'); - utils.log('Lerna publish cmd: ', output); - const isOTPPrompt = _.includes(output, 'Enter OTP:'); - if (isOTPPrompt) { - // Prompt for OTP - prompt.start(); - const result = await promisify(prompt.get)(['OTP']); - child.stdin.write(`${result.OTP}\n`); + return new Promise((resolve, reject) => { + const packageVersionString = _.map(packageToNextVersion, (nextVersion: string, packageName: string) => { + return `${packageName}|${nextVersion}`; + }).join(','); + const cdVersionsFilepath = path.join(__dirname, 'cd_versions.txt'); + fs.writeFileSync(cdVersionsFilepath, packageVersionString); + const lernaPublishCmd = `node`; + const lernaPublishArgs = [ + `${constants.lernaExecutable}`, + 'publish', + `--cdVersions=${cdVersionsFilepath}`, + `--registry=${configs.NPM_REGISTRY_URL}`, + `--yes`, + ]; + if (configs.IS_LOCAL_PUBLISH) { + lernaPublishArgs.push('--no-git-tag-version'); + lernaPublishArgs.push('--no-push'); + } + utils.log('Lerna is publishing...'); + try { + const child = spawn(lernaPublishCmd, lernaPublishArgs, { + cwd: constants.monorepoRootPath, + }); + child.stdout.on('data', async (data: Buffer) => { + const output = data.toString('utf8'); + utils.log('Lerna publish cmd: ', output); + const isOTPPrompt = _.includes(output, 'Enter OTP:'); + if (isOTPPrompt) { + // Prompt for OTP + prompt.start(); + const result = await promisify(prompt.get)(['OTP']); + child.stdin.write(`${result.OTP}\n`); + } + const didFinishPublishing = _.includes(output, 'Successfully published:'); + if (didFinishPublishing) { + // Remove temporary cdVersions file + fs.unlinkSync(cdVersionsFilepath); + resolve(); + } + }); + child.stderr.on('data', (data: Buffer) => { + const output = data.toString('utf8'); + utils.log('Lerna publish cmd: ', output); + }); + } catch (err) { + reject(err); } - }); - child.stderr.on('data', (data: Buffer) => { - const output = data.toString('utf8'); - utils.log('Lerna publish cmd: ', output); }); } From 910bba99764139c87154de07217ff8970bcc8a99 Mon Sep 17 00:00:00 2001 From: fabioberger Date: Wed, 24 Jul 2019 17:19:00 +0200 Subject: [PATCH 3/4] Bump Lerna fork version to include change of cdVersions flag to file path and separator to | between package versions --- package.json | 2 +- yarn.lock | 62 ++++++++++++++++++++++++++++++++++------------------ 2 files changed, 42 insertions(+), 22 deletions(-) diff --git a/package.json b/package.json index 70e732e5f4..14a1a7fd8e 100644 --- a/package.json +++ b/package.json @@ -77,7 +77,7 @@ "graceful-fs": "4.1.15" }, "devDependencies": { - "@0x-lerna-fork/lerna": "3.16.7", + "@0x-lerna-fork/lerna": "3.16.8", "@0xproject/npm-cli-login": "^0.0.11", "async-child-process": "^1.1.1", "bundlewatch": "^0.2.1", diff --git a/yarn.lock b/yarn.lock index 48bb2f1ca8..04a7d2ddf4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -56,16 +56,16 @@ read-package-tree "^5.1.6" semver "^6.2.0" -"@0x-lerna-fork/changed@3.16.7": - version "3.16.7" - resolved "https://registry.yarnpkg.com/@0x-lerna-fork/changed/-/changed-3.16.7.tgz#20529ddb56b951a75d10ed9ebfbc6b4ec9214e7e" - integrity sha512-26F9E0bitgoEYjb9yfJJAkb1ViMmJLTAYypxLatPuvNMFb90y3pq9YSrLXkGTxg8s6pB2uDdRD/JnnDjFge3XQ== +"@0x-lerna-fork/changed@3.16.8": + version "3.16.8" + resolved "https://registry.yarnpkg.com/@0x-lerna-fork/changed/-/changed-3.16.8.tgz#f99767c08c1070506fcca066b829f9b20506c821" + integrity sha512-aQb6NoOrjHZbp+vccVpnIjMlot2oqiFUb+dJB5gH0c+Iw7MGb5KSKkF1lODt76U54VCqT3IsBdHB+U1O7bCWrg== dependencies: "@0x-lerna-fork/collect-updates" "3.16.3" "@0x-lerna-fork/command" "3.16.3" "@0x-lerna-fork/listable" "3.16.3" "@0x-lerna-fork/output" "3.16.3" - "@0x-lerna-fork/version" "3.16.7" + "@0x-lerna-fork/version" "3.16.8" "@0x-lerna-fork/check-working-tree@3.16.3": version "3.16.3" @@ -318,14 +318,14 @@ p-map "^2.1.0" write-json-file "^3.2.0" -"@0x-lerna-fork/lerna@3.16.7": - version "3.16.7" - resolved "https://registry.yarnpkg.com/@0x-lerna-fork/lerna/-/lerna-3.16.7.tgz#0c36ccc46b4dd217f476f9e70a568432cdbc4130" - integrity sha512-wajiUnqJnyU6gQV69isVfaLoRzueMWKzYayMHqzVfXGFNlUH8qc19YLQtD14ec8PQpDIMUlKmhEsQv4KNo9j3Q== +"@0x-lerna-fork/lerna@3.16.8": + version "3.16.8" + resolved "https://registry.yarnpkg.com/@0x-lerna-fork/lerna/-/lerna-3.16.8.tgz#d8c697db74d598f5ee4e18621ee6c353e9151068" + integrity sha512-gkBFBmigBClHQE5JwEP+yE5iuLnY+xEsfUXvSWvpkDN0IOS/kh/74FVbhOzHfrotooA6x+oTOZE5l3cOMOCyuA== dependencies: "@0x-lerna-fork/add" "3.16.3" "@0x-lerna-fork/bootstrap" "3.16.3" - "@0x-lerna-fork/changed" "3.16.7" + "@0x-lerna-fork/changed" "3.16.8" "@0x-lerna-fork/clean" "3.16.3" "@0x-lerna-fork/cli" "3.16.3" "@0x-lerna-fork/create" "3.16.3" @@ -335,9 +335,9 @@ "@0x-lerna-fork/init" "3.16.3" "@0x-lerna-fork/link" "3.16.3" "@0x-lerna-fork/list" "3.16.3" - "@0x-lerna-fork/publish" "3.16.7" + "@0x-lerna-fork/publish" "3.16.8" "@0x-lerna-fork/run" "3.16.3" - "@0x-lerna-fork/version" "3.16.7" + "@0x-lerna-fork/version" "3.16.8" import-local "^2.0.0" npmlog "^4.1.2" @@ -519,10 +519,10 @@ inquirer "^6.2.0" npmlog "^4.1.2" -"@0x-lerna-fork/publish@3.16.7": - version "3.16.7" - resolved "https://registry.yarnpkg.com/@0x-lerna-fork/publish/-/publish-3.16.7.tgz#5f23fbd106eb5dffb5fc15980e03c9edff901519" - integrity sha512-1TLcFi7yOn7FqXoEZf62ND62pPR0OfnBWhRoq3d+b6IUpUl+srkjaznncf0KflJU0ccXMA/2z6uh72IpkvRGCw== +"@0x-lerna-fork/publish@3.16.8": + version "3.16.8" + resolved "https://registry.yarnpkg.com/@0x-lerna-fork/publish/-/publish-3.16.8.tgz#9f2bdf8a6085b33af67dc67c700d48b29ddd032f" + integrity sha512-II9XEvc7nskBTxWwWnim+T+V+IAUSMO3+ffMUd5U9crhSASuWS1tNdBGjNJPMMaqSGzswUEUxI8PjlfcfVEOIw== dependencies: "@0x-lerna-fork/check-working-tree" "3.16.3" "@0x-lerna-fork/child-process" "3.16.3" @@ -542,7 +542,7 @@ "@0x-lerna-fork/run-lifecycle" "3.16.3" "@0x-lerna-fork/run-topologically" "3.16.3" "@0x-lerna-fork/validation-error" "3.16.3" - "@0x-lerna-fork/version" "3.16.7" + "@0x-lerna-fork/version" "3.16.8" "@evocateur/libnpmaccess" "^3.1.2" "@evocateur/npm-registry-fetch" "^4.0.0" "@evocateur/pacote" "^9.6.3" @@ -665,10 +665,10 @@ dependencies: npmlog "^4.1.2" -"@0x-lerna-fork/version@3.16.7": - version "3.16.7" - resolved "https://registry.yarnpkg.com/@0x-lerna-fork/version/-/version-3.16.7.tgz#f223d1ea27716f6b47a87cfd856c95c14f7edb3c" - integrity sha512-WIHT/SnXk49+LzSm65niFm78AyMq+DilDsJ3aGc4eSBEu3ADpMufRNy6ksmI6NB3uk1+KHq/o6at/9vq6bCRMQ== +"@0x-lerna-fork/version@3.16.8": + version "3.16.8" + resolved "https://registry.yarnpkg.com/@0x-lerna-fork/version/-/version-3.16.8.tgz#7e08c81149c82507e50e5c1458b748ba84b1c207" + integrity sha512-g/oPaNUPw0guxhg6J+3mO7R+RjKlCIZY7vX52pgD7ddnW9znmUepClnEoY92CSDnCqXt3YmZEZsDxeSK0gyycQ== dependencies: "@0x-lerna-fork/check-working-tree" "3.16.3" "@0x-lerna-fork/child-process" "3.16.3" @@ -715,6 +715,26 @@ dependencies: "@0x/base-contract" "^5.1.0" +"@0x/abi-gen@^2.1.1": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@0x/abi-gen/-/abi-gen-2.1.1.tgz#2ca9072e64a2a46b6149aaea434f09d5dbf0866f" + integrity sha512-QLigDvQEGe248MjafJ58nWfwMbz+Va6KTlCsrADTuQd711XY10c95poDPevOfAXNHFZYpgS6rEzIau0WmY+Kbw== + dependencies: + "@0x/types" "^2.4.0" + "@0x/typescript-typings" "^4.2.3" + "@0x/utils" "^4.4.0" + chalk "^2.3.0" + change-case "^3.0.2" + cli-format "^3.0.9" + ethereum-types "^2.1.3" + glob "^7.1.2" + handlebars "^4.0.11" + lodash "^4.17.11" + mkdirp "^0.5.1" + tmp "^0.0.33" + to-snake-case "^1.0.0" + yargs "^10.0.3" + "@0x/asset-buyer@6.1.4": version "6.1.4" resolved "https://registry.yarnpkg.com/@0x/asset-buyer/-/asset-buyer-6.1.4.tgz#ea863b860fbae6f633846bdcf23cacbb345aefd1" From fef1bd13b5bd80a82396c297a114ba67168ba341 Mon Sep 17 00:00:00 2001 From: fabioberger Date: Wed, 24 Jul 2019 17:26:54 +0200 Subject: [PATCH 4/4] Add HACK comment about writing cdVersions to a file --- packages/monorepo-scripts/src/publish.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/packages/monorepo-scripts/src/publish.ts b/packages/monorepo-scripts/src/publish.ts index 1cfe3a6414..d5ca4fa284 100644 --- a/packages/monorepo-scripts/src/publish.ts +++ b/packages/monorepo-scripts/src/publish.ts @@ -261,6 +261,10 @@ async function lernaPublishAsync(packageToNextVersion: { [name: string]: string const packageVersionString = _.map(packageToNextVersion, (nextVersion: string, packageName: string) => { return `${packageName}|${nextVersion}`; }).join(','); + // HACK(fabio): Previously we would pass the packageVersionString directly to `lerna publish` using the + // `--cdVersions` flag. Since we now need to use `spawn` instead of `exec` when calling Lerna, passing + // them as a string arg is causing `spawn` to error with `ENAMETOOLONG`. In order to shorten the args + // passed to `spawn` we now write the new version to a file and pass the filepath to the `cdVersions` arg. const cdVersionsFilepath = path.join(__dirname, 'cd_versions.txt'); fs.writeFileSync(cdVersionsFilepath, packageVersionString); const lernaPublishCmd = `node`; @@ -302,6 +306,8 @@ async function lernaPublishAsync(packageToNextVersion: { [name: string]: string utils.log('Lerna publish cmd: ', output); }); } catch (err) { + // Remove temporary cdVersions file + fs.unlinkSync(cdVersionsFilepath); reject(err); } });