diff --git a/commands/publish/README.md b/commands/publish/README.md index a366b2700e..7d4b23a538 100644 --- a/commands/publish/README.md +++ b/commands/publish/README.md @@ -51,6 +51,7 @@ This is useful when a previous `lerna publish` failed to publish all packages to - [`--git-head `](#--git-head-sha) - [`--no-git-reset`](#--no-git-reset) - [`--no-verify-access`](#--no-verify-access) +- [`--otp`](#--otp) - [`--preid`](#--preid) - [`--pre-dist-tag `](#--pre-dist-tag-tag) - [`--registry `](#--registry-url) @@ -141,6 +142,16 @@ If you are using a third-party registry that does not support `npm access ls-pac > Please use with caution +### `--otp` + +When publishing packages that require two-factor authentication, you can specify a [one-time password](https://docs.npmjs.com/about-two-factor-authentication) using `--otp`: + +```sh +lerna publish --otp 123456 +``` + +> Please keep in mind that one-time passwords expire within 30 seconds of their generation. If it expires during publish operations, a prompt will request a refreshed value before continuing. + ### `--preid` Unlike the `lerna version` option of the same name, this option only applies to [`--canary`](#--canary) version calculation. @@ -211,7 +222,7 @@ Keep in mind that currently you have to supply it twice: for `version` command a # locally lerna version --tag-version-prefix='' # on ci -lerna publish from-git --tag-version-prefix='' +lerna publish from-git --tag-version-prefix='' ``` ## Deprecated Options @@ -271,6 +282,7 @@ Lerna will run [npm lifecycle scripts](https://docs.npmjs.com/misc/scripts#descr ### Pre Publish - In root package: + - `prepublish` - `prepare` - `prepublishOnly` diff --git a/commands/publish/__tests__/publish-command.test.js b/commands/publish/__tests__/publish-command.test.js index eadfade610..4ab7db6fe9 100644 --- a/commands/publish/__tests__/publish-command.test.js +++ b/commands/publish/__tests__/publish-command.test.js @@ -166,6 +166,22 @@ Map { }); }); + describe("--otp", () => { + it("passes one-time password to npm commands", async () => { + const testDir = await initFixture("normal"); + const otp = "123456"; + + await lernaPublish(testDir)("--otp", otp); + + expect(npmPublish).toHaveBeenCalledWith( + expect.objectContaining({ name: "package-1" }), + "/TEMP_DIR/package-1-MOCKED.tgz", + expect.objectContaining({ otp }), + expect.objectContaining({ otp }) + ); + }); + }); + describe("--registry", () => { it("passes registry to npm commands", async () => { const testDir = await initFixture("normal"); diff --git a/commands/publish/command.js b/commands/publish/command.js index b1f2b7b580..6c996ca1e0 100644 --- a/commands/publish/command.js +++ b/commands/publish/command.js @@ -41,6 +41,11 @@ exports.builder = yargs => { type: "string", requiresArg: true, }, + otp: { + describe: "Supply a one-time password for publishing with two-factor authentication.", + type: "string", + requiresArg: true, + }, registry: { describe: "Use the specified registry for all npm client operations.", type: "string", diff --git a/commands/publish/index.js b/commands/publish/index.js index abb7e1be2c..9ad5e260b1 100644 --- a/commands/publish/index.js +++ b/commands/publish/index.js @@ -93,11 +93,13 @@ class PublishCommand extends Command { this.logger.verbose("user-agent", userAgent); // cache to hold a one-time-password across publishes - this.otpCache = { otp: undefined }; + this.otpCache = { otp: this.options.otp }; + this.conf = npmConf({ lernaCommand: "publish", npmSession, npmVersion: userAgent, + otp: this.options.otp, registry: this.options.registry, });