Skip to content
Permalink
Browse files

feat(version): Ignore private packages completely with `--no-private`

- No more spurious tags for unpublished packages
- No more mutation of private manifest versions
- No more redundant checking for previous releases of private packages

Configure this option in lerna.json for greatest consistency:
```
{
  "command": {
    "version": {
      "private": false
    }
  },
  "version": "1.2.3"
}
```
(version can be whatever it is already, included for illustrative purposes)
  • Loading branch information
evocateur committed May 12, 2020
1 parent 4691b93 commit a9b9f97457e4e4b0cac7f4ce562458d921a1f9be
@@ -401,3 +401,30 @@ test("publish --canary without _any_ tags (independent)", async () => {
}
`);
});

test("publish --canary --no-private", async () => {
// mostly to say, "yay you didn't explode!"
// publish always skips private packages already
const cwd = await initTaggedFixture("independent");
await setupChanges(
cwd,
["packages/package-1/all-your-base.js", "belong to us"],
[
"packages/package-3/package.json",
JSON.stringify({
name: "package-3",
version: "3.0.0",
private: true,
}),
]
);

await lernaPublish(cwd)("--canary", "--no-private");

expect(writePkg.updatedVersions()).toMatchInlineSnapshot(`
Object {
"package-1": 1.0.1-alpha.0+SHA,
"package-2": 2.0.1-alpha.0+SHA,
}
`);
});
@@ -60,6 +60,7 @@ Running `lerna version --conventional-commits` without the above flags will rele
- [`--no-changelog`](#--no-changelog)
- [`--no-commit-hooks`](#--no-commit-hooks)
- [`--no-git-tag-version`](#--no-git-tag-version)
- [`--no-private`](#--no-private)
- [`--no-push`](#--no-push)
- [`--preid`](#--preid)
- [`--sign-git-commit`](#--sign-git-commit)
@@ -317,6 +318,13 @@ Pass `--no-git-tag-version` to disable the behavior.

This option is analogous to the `npm version` option [`--git-tag-version`](https://docs.npmjs.com/misc/config#git-tag-version), just inverted.

### `--no-private`

By default, `lerna version` will include private packages when choosing versions, making commits, and tagging releases.
Pass `--no-private` to disable this behavior.

Note that this option does _not_ exclude [private scoped packages](https://docs.npmjs.com/about-private-packages), only those with a [`"private": true` field](https://docs.npmjs.com/configuring-npm/package-json.html#private) in their package.json file.

### `--no-push`

By default, `lerna version` will push the committed and tagged changes to the configured [git remote](#--git-remote-name).
@@ -137,6 +137,8 @@ test("independent version prerelease does not bump on every unrelated change", a
"package.json": File({
name: "pkg-b",
version: "1.0.0-bumps.1",
// TODO: (major) make --no-private the default
private: true,
}),
}),
}),
@@ -180,3 +182,54 @@ Publish
- pkg-a@1.0.2
`);
});

test("independent version prerelease respects --no-private", async () => {
const cwd = tempy.directory();
const fixture = new Tacks(
Dir({
"lerna.json": File({
version: "independent",
}),
"package.json": File({
name: "no-private-versioning",
}),
packages: Dir({
"pkg-1": Dir({
"package.json": File({
name: "pkg-1",
version: "1.0.0",
devDependencies: {
"pkg-2": "^2.0.0",
},
}),
}),
"pkg-2": Dir({
"package.json": File({
name: "pkg-2",
version: "2.0.0",
private: true,
}),
}),
}),
})
);
fixture.create(cwd);

await gitInit(cwd, ".");
await gitAdd(cwd, "-A");
await gitCommit(cwd, "init");

// TODO: (major) make --no-private the default
await lernaVersion(cwd)("prerelease", "--no-private");

const changedFiles = await showCommit(cwd, "--name-only");
expect(changedFiles).toMatchInlineSnapshot(`
Publish
- pkg-1@1.0.1-alpha.0
HEAD -> master, tag: pkg-1@1.0.1-alpha.0
packages/pkg-1/package.json
`);
});
@@ -94,6 +94,8 @@ describe("version bump", () => {

const message = await getCommitMessage(testDir);
expect(message).toContain("package-1@1.0.1-alpha.0");
// TODO: (major) make --no-private the default
expect(message).toContain("package-5@5.0.1-alpha.0");
});

test("prerelease increments version with custom --preid", async () => {
@@ -104,4 +106,14 @@ describe("version bump", () => {
const message = await getCommitMessage(testDir);
expect(message).toContain("package-1@1.0.1-foo.0");
});

it("ignores private packages with --no-private", async () => {
const testDir = await initFixture("independent");

await lernaVersion(testDir)("patch", "--no-private");

const message = await getCommitMessage(testDir);
// TODO: (major) make --no-private the default
expect(message).not.toContain("package-5");
});
});
@@ -156,6 +156,21 @@ describe("VersionCommand", () => {
const patch = await showCommit(testDir);
expect(patch).toMatchSnapshot();
});

it("does not bump major of private packages with --no-private", async () => {
const testDir = await initFixture("normal");

// despite being a pendant leaf...
collectUpdates.setUpdated(testDir, "package-4");
PromptUtilities.mockChoices("major");

await lernaVersion(testDir)("--no-private");

const patch = await showCommit(testDir, "--name-only");
expect(patch).not.toContain("package-5");
// ...all packages are still majored
expect(patch).toContain("package-1");
});
});

describe("independent mode", () => {
@@ -281,6 +296,42 @@ describe("VersionCommand", () => {
});
});

// TODO: (major) make --no-private the default
describe("--no-private", () => {
it("does not universally version private packages", async () => {
const testDir = await initFixture("normal");
await lernaVersion(testDir)("--no-private");

const patch = await showCommit(testDir, "--name-only");
expect(patch).not.toContain("package-5");
});

it("does not independently version private packages", async () => {
const testDir = await initFixture("independent");
await lernaVersion(testDir)("--no-private");

const patch = await showCommit(testDir, "--name-only");
expect(patch).not.toContain("package-5");
});

it("consumes configuration from lerna.json", async () => {
const testDir = await initFixture("normal");

await fs.outputJSON(path.join(testDir, "lerna.json"), {
version: "1.0.0",
command: {
version: {
private: false,
},
},
});
await lernaVersion(testDir)();

const patch = await showCommit(testDir, "--name-only");
expect(patch).not.toContain("package-5");
});
});

describe("--no-push", () => {
it("versions changed packages without git push", async () => {
const testDir = await initFixture("normal");
@@ -141,6 +141,15 @@ describe("--conventional-commits", () => {

expect(ConventionalCommitUtilities.updateChangelog).not.toHaveBeenCalled();
});

it("should respect --no-private", async () => {
const cwd = await initFixture("independent");
// TODO: (major) make --no-private the default
await lernaVersion(cwd)("--conventional-commits", "--no-private");

const changedFiles = await showCommit(cwd, "--name-only");
expect(changedFiles).not.toContain("package-5");
});
});

describe("fixed mode", () => {
@@ -273,6 +282,15 @@ describe("--conventional-commits", () => {

expect(ConventionalCommitUtilities.updateChangelog).not.toHaveBeenCalled();
});

it("should respect --no-private", async () => {
const cwd = await initFixture("normal");
// TODO: (major) make --no-private the default
await lernaVersion(cwd)("--conventional-commits", "--no-private");

const changedFiles = await showCommit(cwd, "--name-only");
expect(changedFiles).not.toContain("package-5");
});
});

it("avoids duplicating previously-released version", async () => {
@@ -105,6 +105,16 @@ exports.builder = (yargs, composed) => {
hidden: true,
type: "boolean",
},
// TODO: (major) make --no-private the default
"no-private": {
describe: "Do not version private packages.",
type: "boolean",
},
private: {
// proxy for --no-private
hidden: true,
type: "boolean",
},
"no-push": {
describe: "Do not push tagged commit to git remote.",
type: "boolean",
@@ -191,6 +191,12 @@ class VersionCommand extends Command {
this.execOpts,
this.options
).filter(node => {
// --no-private completely removes private packages from consideration
if (node.pkg.private && this.options.private === false) {
// TODO: (major) make --no-private the default
return false;
}

if (!node.version) {
// a package may be unversioned only if it is private
if (node.pkg.private) {
@@ -439,6 +445,13 @@ class VersionCommand extends Command {
if (hasBreakingChange) {
// _all_ packages need a major version bump whenever _any_ package does
this.updates = Array.from(this.packageGraph.values());

// --no-private completely removes private packages from consideration
if (this.options.private === false) {
// TODO: (major) make --no-private the default
this.updates = this.updates.filter(node => !node.pkg.private);
}

this.updatesVersions = new Map(this.updates.map(({ name }) => [name, this.globalVersion]));
} else {
this.updatesVersions = versions;

0 comments on commit a9b9f97

Please sign in to comment.
You can’t perform that action at this time.