calver-bump 0.1.6 → 0.1.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "calver-bump",
3
- "version": "0.1.6",
3
+ "version": "0.1.7",
4
4
  "description": "Release CLI for internal applications using readable CalVer versions.",
5
5
  "main": "src/index.js",
6
6
  "bin": {
package/src/index.js CHANGED
@@ -152,7 +152,7 @@ async function releaseNotes(cwd, options = {}) {
152
152
  const compareUrlBuilder = remoteUrl ? buildCompareUrlBuilder(remoteUrl) : null;
153
153
  const requestUrlBuilder = remoteUrl ? buildRequestUrlBuilder(remoteUrl) : null;
154
154
  const allowedTypes = options.types ?? ['feat', 'fix', 'docs', 'style', 'refactor', 'perf', 'test', 'build', 'ci', 'chore', 'revert'];
155
- const conventionalCommits = commits
155
+ const conventionalCommits = dedupeConventionalChanges(commits
156
156
  .map((commit) => ({ ...commit, subject: conventionalSubjectForCommit(commit) ?? commit.subject }))
157
157
  .filter((commit) => isConventionalCommit(commit.subject))
158
158
  .filter((commit) => allowedTypes.includes(conventionalType(commit.subject)))
@@ -161,7 +161,7 @@ async function releaseNotes(cwd, options = {}) {
161
161
  ...commit,
162
162
  request: requestForCommit(commit, requestUrlBuilder),
163
163
  url: commitUrlBuilder ? commitUrlBuilder(commit.hash) : null,
164
- }));
164
+ })));
165
165
  const requests = uniqueRequests(commits.map((commit) => requestForCommit(commit, requestUrlBuilder)).filter(Boolean));
166
166
  return {
167
167
  previousTag: latestTag,
@@ -197,6 +197,21 @@ function commitLines(commit) {
197
197
  .filter(Boolean);
198
198
  }
199
199
 
200
+ function dedupeConventionalChanges(changes) {
201
+ const deduped = [];
202
+ for (const change of changes) {
203
+ const existingIndex = deduped.findIndex((candidate) => candidate.subject === change.subject);
204
+ if (existingIndex < 0) {
205
+ deduped.push(change);
206
+ continue;
207
+ }
208
+ if (!deduped[existingIndex].request && change.request) {
209
+ deduped[existingIndex] = change;
210
+ }
211
+ }
212
+ return deduped;
213
+ }
214
+
200
215
  function formatReleaseNotes(changes) {
201
216
  if (changes.length === 1 && changes[0] === 'No conventional commits in this release.') {
202
217
  return `- ${changes[0]}`;
@@ -303,6 +303,40 @@ test('runRelease links changelog entries to GitLab merge requests and dedupes th
303
303
  );
304
304
  });
305
305
 
306
+ test('runRelease prefers merge request entries over duplicate commit hash entries', async () => {
307
+ const repo = await makeRepo();
308
+ execFileSync('git', ['remote', 'add', 'origin', 'git@gitlab.internal.example.com:platform/demo-app.git'], { cwd: repo });
309
+ execFileSync('git', ['tag', 'v1.0.0'], { cwd: repo });
310
+ await writeFile(path.join(repo, 'raw-fix.txt'), 'raw\n');
311
+ execFileSync('git', ['add', 'raw-fix.txt'], { cwd: repo });
312
+ execFileSync('git', ['commit', '-m', 'fix(review): block rule-listed reviewers'], { cwd: repo });
313
+ const rawHash = execFileSync('git', ['rev-parse', 'HEAD'], { cwd: repo, encoding: 'utf8' }).trim();
314
+ await writeFile(path.join(repo, 'merge-fix.txt'), 'merge\n');
315
+ execFileSync('git', ['add', 'merge-fix.txt'], { cwd: repo });
316
+ execFileSync('git', [
317
+ 'commit',
318
+ '-m',
319
+ 'Merge branch feature/review into main',
320
+ '-m',
321
+ 'fix(review): block rule-listed reviewers',
322
+ '-m',
323
+ 'See merge request platform/demo-app!77',
324
+ ], { cwd: repo });
325
+
326
+ await runRelease({
327
+ cwd: repo,
328
+ date: new Date('2026-05-29T12:00:00-07:00'),
329
+ });
330
+
331
+ const changelog = await readFile(path.join(repo, 'CHANGELOG.md'), 'utf8');
332
+ const fixes = changelog.match(/### Fixes\n\n(?<body>[\s\S]*?)(?:\n\n###|\n?$)/)?.groups.body ?? '';
333
+ assert.match(
334
+ fixes,
335
+ /- fix\(review\): block rule-listed reviewers \(\[!77\]\(https:\/\/gitlab\.internal\.example\.com\/platform\/demo-app\/-\/merge_requests\/77\)\)/,
336
+ );
337
+ assert.doesNotMatch(fixes, new RegExp(rawHash.slice(0, 7)));
338
+ });
339
+
306
340
  test('runRelease prepends only commits since the previous CalVer tag on later releases', async () => {
307
341
  const repo = await makeRepo();
308
342
  await runRelease({