Skip to content

Commit

Permalink
fix(publish): Set token on npm config, allow third-party registries t…
Browse files Browse the repository at this point in the history
…o remain non-compliant
  • Loading branch information
evocateur committed Oct 4, 2018
1 parent 987fd26 commit 06a9479
Show file tree
Hide file tree
Showing 7 changed files with 64 additions and 16 deletions.
26 changes: 25 additions & 1 deletion commands/publish/__tests__/get-npm-username.test.js
Expand Up @@ -3,6 +3,7 @@
jest.mock("npm-registry-fetch");

const fetch = require("npm-registry-fetch");
const loggingOutput = require("@lerna-test/logging-output");
const getNpmUsername = require("../lib/get-npm-username");

fetch.json.mockImplementation(() => Promise.resolve({ username: "lerna-test" }));
Expand Down Expand Up @@ -50,8 +51,11 @@ describe("getNpmUsername", () => {
return Promise.reject(err);
});

const opts = new Map();
opts.set("registry", "https://registry.npmjs.org/");

try {
await getNpmUsername({ stub: true });
await getNpmUsername(opts);
} catch (err) {
expect(err.prefix).toBe("EWHOAMI");
expect(err.message).toBe("Authentication error. Use `npm whoami` to troubleshoot.");
Expand All @@ -60,4 +64,24 @@ describe("getNpmUsername", () => {

expect.assertions(3);
});

test("allows third-party registries to fail with a stern warning", async () => {
fetch.json.mockImplementationOnce(() => {
const err = new Error("many third-party registries do not support npm whoami");

err.code = "E401";

return Promise.reject(err);
});

const opts = new Map();
opts.set("registry", "http://my-own-private-idaho.com");

const username = await getNpmUsername(opts);

expect(username).toBeUndefined();
expect(loggingOutput("warn")).toContain(
"Unable to determine npm username from third-party registry, this command will likely fail soon!"
);
});
});
10 changes: 10 additions & 0 deletions commands/publish/__tests__/publish-command.test.js
Expand Up @@ -261,6 +261,16 @@ Set {

expect(verifyNpmPackageAccess).not.toBeCalled();
});

it("is implied when npm username is undefined", async () => {
getNpmUsername.mockImplementationOnce(() => Promise.resolve());

const cwd = await initFixture("normal");

await lernaPublish(cwd)("--registry", "https://my-private-registry");

expect(verifyNpmPackageAccess).not.toBeCalled();
});
});

describe("in a cyclical repo", () => {
Expand Down
22 changes: 18 additions & 4 deletions commands/publish/index.js
Expand Up @@ -66,10 +66,23 @@ class PublishCommand extends Command {
// https://docs.npmjs.com/misc/config#save-prefix
this.savePrefix = this.options.exact ? "" : "^";

this.conf = npmConf(this.options);
const { registry, npmClient = "npm" } = this.options;

this.conf = npmConf({
log: this.logger,
registry,
});

// all consumers need a token
const auth = this.conf.getCredentialsByURI(this.conf.get("registry"));

if (auth.token) {
this.conf.set("token", auth.token, "cli");
}

this.npmConfig = {
npmClient: this.options.npmClient || "npm",
registry: this.options.registry,
npmClient,
registry: this.conf.get("registry"),
};

let chain = Promise.resolve();
Expand Down Expand Up @@ -325,7 +338,8 @@ class PublishCommand extends Command {
return chain;
}

if (this.verifyAccess) {
// if no username was retrieved, don't bother validating
if (this.conf.get("username") && this.verifyAccess) {
chain = chain.then(() => verifyNpmPackageAccess(this.packagesToPublish, this.conf));
}

Expand Down
2 changes: 1 addition & 1 deletion commands/publish/lib/__mocks__/get-npm-username.js
Expand Up @@ -4,7 +4,7 @@ const registry = new Map();

// to mock user modules, you _must_ call `jest.mock('./path/to/module')`
const mockGetNpmUsername = jest.fn(opts => {
registry.set(opts.get("cwd"), opts);
registry.set(opts.prefix, opts);

return Promise.resolve("lerna-test");
});
Expand Down
Expand Up @@ -8,7 +8,7 @@ const mockVerifyNpmPackageAccess = jest.fn((packages, opts) => {

result.add(`username: ${opts.get("username")}`);

registry.set(opts.get("cwd"), result);
registry.set(opts.prefix, result);

return Promise.resolve();
});
Expand Down
9 changes: 8 additions & 1 deletion commands/publish/lib/get-npm-username.js
Expand Up @@ -31,6 +31,13 @@ function getNpmUsername(opts) {
console.error(err.message); // eslint-disable-line no-console
log.resume();

throw new ValidationError("EWHOAMI", "Authentication error. Use `npm whoami` to troubleshoot.");
if (opts.get("registry") === "https://registry.npmjs.org/") {
throw new ValidationError("EWHOAMI", "Authentication error. Use `npm whoami` to troubleshoot.");
}

log.warn(
"EWHOAMI",
"Unable to determine npm username from third-party registry, this command will likely fail soon!"
);
}
}
9 changes: 1 addition & 8 deletions integration/lerna-publish-lifecycle-errors.test.js
Expand Up @@ -19,7 +19,7 @@ const env = {

test("lerna publish lifecycle scripts stop on non-zero exit", async () => {
const { cwd } = await cloneFixture("lifecycle");
const args = ["publish", "minor", "--yes"];
const args = ["publish", "minor", "--loglevel", "error", "--yes"];

const rootManifest = path.join(cwd, "package.json");
const json = await fs.readJson(rootManifest);
Expand Down Expand Up @@ -51,13 +51,6 @@ boom
`);
expect(err.stderr).toMatchInlineSnapshot(`
lerna notice cli __TEST_VERSION__
lerna info Verifying npm credentials
lerna info current version 1.0.0
lerna info Looking for changed packages since initial commit.
lerna info auto-confirmed
lerna info lifecycle lifecycle@0.0.0-monorepo~preversion: lifecycle@0.0.0-monorepo
lerna info lifecycle lifecycle@0.0.0-monorepo~preversion: Failed to exec preversion script
lerna ERR! lifecycle "preversion" errored in "lifecycle", exiting 123
`);
Expand Down

0 comments on commit 06a9479

Please sign in to comment.