Skip to content

Commit

Permalink
feat(conventional-commits): Preserve major version zero on breaking c…
Browse files Browse the repository at this point in the history
…hanges (#2486)

According to semver, major version zero (0.y.z) is for initial
development. Anything MAY change at any time. The public API
SHOULD NOT be considered stable. The version 1.0.0 defines
the (initial stable) public API.

To allow monorepos to use major version zero meaningfully,
the transition from 0.x to 1.x must be explicitly requested
by the user. Breaking changes MUST NOT automatically bump
the major version from 0.x to 1.x.

The usual convention is to use semver-patch bumps for bugfix
releases and semver-minor for everything else, including
breaking changes. This matches the behavior of `^` operator
as implemented by `npm`.

This commit implements the convention described above:
- a patch-level change bumps semver-patch version (NO CHANGE)
- a minor-level change bumps semver-minor version (NO CHANGE)
- a major-level (breaking) change bumps semver-minor version (NEW)

Signed-off-by: Miroslav Bajtoš <mbajtoss@gmail.com>
  • Loading branch information
bajtos committed May 24, 2020
1 parent 5d80285 commit 6126e6c
Show file tree
Hide file tree
Showing 8 changed files with 59 additions and 1 deletion.
@@ -0,0 +1,8 @@
{
"command": {
"publish": {
"conventionalCommits": true
}
},
"version": "independent"
}
@@ -0,0 +1,5 @@
{
"name": "conventional-commits-major-zero",
"repository": "lerna/conventional-commits-major-zero",
"version": "0.0.0-root"
}
Empty file.
@@ -0,0 +1,5 @@
{
"name": "package-0",
"repository": "lerna/conventional-commits-major-zero",
"version": "0.1.0"
}
Empty file.
@@ -0,0 +1,5 @@
{
"name": "package-1",
"repository": "lerna/conventional-commits-major-zero",
"version": "1.0.0"
}
15 changes: 15 additions & 0 deletions core/conventional-commits/__tests__/conventional-commits.test.js
Expand Up @@ -217,6 +217,21 @@ describe("conventional-commits", () => {
).rejects.toThrow("Unable to load conventional-changelog preset 'conventional-changelog-garbage/pail'");
});

describe("bump for major version zero", () => {
it("treats breaking changes as semver-minor", async () => {
const cwd = await initFixture("major-zero");
const [pkg0] = await getPackages(cwd);

// make a change in package-0
await pkg0.set("changed", 1).serialize();
await gitAdd(cwd, pkg0.manifestLocation);
await gitCommit(cwd, "feat: changed\n\nBREAKING CHANGE: changed");

const bump = await recommendVersion(pkg0, "independent", {});
expect(bump).toBe("0.2.0");
});
});

describe("prerelease bumps", () => {
let cwd;
let pkg;
Expand Down
22 changes: 21 additions & 1 deletion core/conventional-commits/lib/recommend-version.js
Expand Up @@ -51,14 +51,34 @@ function recommendVersion(pkg, type, { changelogPreset, rootPath, tagPrefix, pre

// result might be undefined because some presets are not consistent with angular
// we still need to bump _something_ because lerna saw a change here
const releaseType = data.releaseType || "patch";
let releaseType = data.releaseType || "patch";

if (prereleaseId) {
const shouldBump = shouldBumpPrerelease(releaseType, pkg.version);
const prereleaseType = shouldBump ? `pre${releaseType}` : "prerelease";
log.verbose(type, "increment %s by %s", pkg.version, prereleaseType);
resolve(semver.inc(pkg.version, prereleaseType, prereleaseId));
} else {
if (semver.major(pkg.version) === 0) {
// According to semver, major version zero (0.y.z) is for initial
// development. Anything MAY change at any time. The public API
// SHOULD NOT be considered stable. The version 1.0.0 defines
// the (initial stable) public API.
//
// To allow monorepos to use major version zero meaningfully,
// the transition from 0.x to 1.x must be explicitly requested
// by the user. Breaking changes MUST NOT automatically bump
// the major version from 0.x to 1.x.
//
// The usual convention is to use semver-patch bumps for bugfix
// releases and semver-minor for everything else, including
// breaking changes. This matches the behavior of `^` operator
// as implemented by `npm`.
//
if (releaseType === "major") {
releaseType = "minor";
}
}
log.verbose(type, "increment %s by %s", pkg.version, releaseType);
resolve(semver.inc(pkg.version, releaseType));
}
Expand Down

0 comments on commit 6126e6c

Please sign in to comment.