Skip to content

Commit 3d05dc5

Browse files
authoredMay 8, 2020
Update: Major version changelogs include all prereleases (#37)
* Update: Major version changelogs include all prereleases For a new stable release following a prerelease sequence, the changelog will include the commits for all of the prereleases going back to the last stable release. For example, given the following release sequence: - 6.7.8 - 6.8.0 - 7.0.0-alpha.0 - 7.0.0-alpha.1 - 7.0.0 The `7.0.0` changelog will include all changes since 6.8.0, whereas the `7.0.0-alpha.1` changelog will include only changes since `7.0.0-alpha.0`. If we prefer to include all changes going back to the previous stable release even for prerelease changelogs, that's an easy change and actually simplifies the logic a bit. * Update comment about version tags
1 parent 13d962b commit 3d05dc5

File tree

2 files changed

+95
-4
lines changed

2 files changed

+95
-4
lines changed
 

‎lib/release-ops.js

+33-4
Original file line numberDiff line numberDiff line change
@@ -250,18 +250,46 @@ function calculateReleaseFromGitLogs(currentVersion, logs, prereleaseId) {
250250
}
251251

252252
/**
253-
* Gets all changes since the last tag that represents a version.
253+
* Gets the range of commits to include in a changelog.
254+
* If this will be the first stable release following a prerelease sequence,
255+
* all commits going back to the previous stable release are included.
256+
* @param {string[]} tags All prior version tags.
257+
* @param {string} [prereleaseId] The prerelease identifier if this is a prerelease.
258+
* @returns {string} The commit range to include in the changelog.
259+
* @private
260+
*/
261+
function getChangelogCommitRange(tags, prereleaseId) {
262+
let lastTag = null;
263+
264+
// If this will be a stable release after a prerelease...
265+
if (!prereleaseId && semver.prerelease(tags[tags.length - 1])) {
266+
let i = 2;
267+
268+
do {
269+
lastTag = tags[tags.length - i];
270+
i++;
271+
} while (semver.prerelease(lastTag));
272+
} else {
273+
lastTag = tags[tags.length - 1];
274+
}
275+
276+
return lastTag ? `${lastTag}..HEAD` : "";
277+
}
278+
279+
/**
280+
* Gets all changes for this release.
281+
* If this will be the first stable release following a prerelease sequence,
282+
* all changes from all prereleases since the last stable release are included.
254283
* @param {string} [prereleaseId] The prerelease identifier if this is a prerelease.
255284
* @returns {Object} An object containing all the changes since the last version.
256285
* @private
257286
*/
258287
function calculateReleaseInfo(prereleaseId) {
259288

260-
// get most recent tag
289+
// get last version tag
261290
const pkg = getPackageInfo(),
262291
tags = getVersionTags(),
263-
lastTag = tags[tags.length - 1],
264-
commitRange = lastTag ? `${lastTag}..HEAD` : "";
292+
commitRange = getChangelogCommitRange(tags, prereleaseId);
265293

266294
// get log statements
267295
const logs = ShellOps.execSilent(`git log --no-merges --pretty=format:"* %H %s (%an)%n%b" ${commitRange}`).split(/\n/g);
@@ -427,6 +455,7 @@ module.exports = {
427455
generateRelease,
428456
publishRelease,
429457
calculateReleaseInfo,
458+
getChangelogCommitRange,
430459
calculateReleaseFromGitLogs,
431460
writeChangelog
432461
};

‎tests/lib/release-ops.js

+62
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,38 @@ describe("ReleaseOps", () => {
4646

4747
});
4848

49+
describe("getChangelogCommitRange", () => {
50+
51+
it("returns an empty string when there are no prior releases", () => {
52+
const tags = [];
53+
const range = ReleaseOps.getChangelogCommitRange(tags);
54+
55+
assert.strictEqual(range, "");
56+
});
57+
58+
it("finds the most recent tag for normal releases", () => {
59+
const tags = ["1.0.0", "1.0.1"];
60+
const range = ReleaseOps.getChangelogCommitRange(tags);
61+
62+
assert.strictEqual(range, "1.0.1..HEAD");
63+
});
64+
65+
it("finds the most recent tag for prereleases", () => {
66+
const tags = ["1.0.0", "1.0.1", "2.0.0-alpha.0", "2.0.0-alpha.1"];
67+
const range = ReleaseOps.getChangelogCommitRange(tags, "beta");
68+
69+
assert.strictEqual(range, "2.0.0-alpha.1..HEAD");
70+
});
71+
72+
it("finds the last stable tag for a new stable following prereleases", () => {
73+
const tags = ["1.0.0", "1.0.1", "2.0.0-alpha.0", "2.0.0-rc.0"];
74+
const range = ReleaseOps.getChangelogCommitRange(tags);
75+
76+
assert.strictEqual(range, "1.0.1..HEAD");
77+
});
78+
79+
});
80+
4981
describe("calculateReleaseFromGitLogs()", () => {
5082

5183
it("should create a patch release when only bug fixes are present", () => {
@@ -252,6 +284,36 @@ describe("ReleaseOps", () => {
252284
});
253285
});
254286

287+
it("should create the next stable release following a prerelease", () => {
288+
const logs = [
289+
"* 7e8a43b2b6350e13a61858f33b4099c964cdd758 Breaking: Remove API (githubhandle)",
290+
"* 0c07d6ac037076557e34d569cd0290e529b3318a Docs: Something else (Committer Name)",
291+
"* 196d32dbfb7cb37b886e7c4ba0adff499c6b26ac Fix: Something else (Abc D. Efg)"
292+
],
293+
releaseInfo = ReleaseOps.calculateReleaseFromGitLogs("2.0.0-rc.0", logs);
294+
295+
assert.deepStrictEqual(releaseInfo, {
296+
version: "2.0.0",
297+
type: "major",
298+
changelog: {
299+
fix: [
300+
"* [`196d32d`](https://github.com/eslint/eslint-release/commit/196d32dbfb7cb37b886e7c4ba0adff499c6b26ac) Fix: Something else (Abc D. Efg)"
301+
],
302+
docs: [
303+
"* [`0c07d6a`](https://github.com/eslint/eslint-release/commit/0c07d6ac037076557e34d569cd0290e529b3318a) Docs: Something else (Committer Name)"
304+
],
305+
breaking: [
306+
"* [`7e8a43b`](https://github.com/eslint/eslint-release/commit/7e8a43b2b6350e13a61858f33b4099c964cdd758) Breaking: Remove API (githubhandle)"
307+
]
308+
},
309+
rawChangelog: [
310+
"* [`7e8a43b`](https://github.com/eslint/eslint-release/commit/7e8a43b2b6350e13a61858f33b4099c964cdd758) Breaking: Remove API (githubhandle)",
311+
"* [`0c07d6a`](https://github.com/eslint/eslint-release/commit/0c07d6ac037076557e34d569cd0290e529b3318a) Docs: Something else (Committer Name)",
312+
"* [`196d32d`](https://github.com/eslint/eslint-release/commit/196d32dbfb7cb37b886e7c4ba0adff499c6b26ac) Fix: Something else (Abc D. Efg)"
313+
].join("\n")
314+
});
315+
});
316+
255317
it("should gracefully handle unformatted commit messages", () => {
256318
const logs = [
257319
"* 70222e95932d3a391ac5717252e13b478d686ba9 0.4.0-alpha.4 (Nicholas C. Zakas)",

0 commit comments

Comments
 (0)
Please sign in to comment.