Skip to content

Commit 3b3779c

Browse files
author
Guilherme Prezzi
committed
fix(semver): commitParserOptions support in changelog and semver bump
1 parent 94dfda6 commit 3b3779c

File tree

9 files changed

+111
-18
lines changed

9 files changed

+111
-18
lines changed

packages/semver/src/executors/version/__snapshots__/index.e2e.spec.ts.snap

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,3 +314,24 @@ This file was generated using [@jscutlery/semver](https://github.com/jscutlery/s
314314
* **a:** 🚀 new feature xxxxxxx
315315
"
316316
`;
317+
318+
exports[`@jscutlery/semver @jscutlery/semver:version when using commitParserOptions and libs/d changed (v0.1.0 => v0.2.0) should generate CHANGELOG.md properly: d-0.2.0 1`] = `
319+
"# Changelog
320+
321+
This file was generated using [@jscutlery/semver](https://github.com/jscutlery/semver).
322+
323+
## [0.2.0](///compare/d-0.1.0...d-0.2.0) (yyyy-mm-dd)
324+
325+
326+
### ✨ Awesome features
327+
328+
* **d:** 🚀 new feature xxxxxxx
329+
330+
## 0.1.0 (yyyy-mm-dd)
331+
332+
333+
### ✨ Awesome features
334+
335+
* **d:** 🚀 new awesome feature xxxxxxx
336+
"
337+
`;

packages/semver/src/executors/version/index.e2e.spec.ts

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
import { execSync } from 'child_process';
22
import { setupTestingWorkspace, type TestingWorkspace } from './testing';
33
import { readFileSync, existsSync } from 'fs';
4+
import { ProjectConfiguration } from '@nx/devkit';
5+
import { writeFile } from './utils/filesystem';
6+
import { firstValueFrom } from 'rxjs';
47

58
describe('@jscutlery/semver', () => {
69
let testingWorkspace: TestingWorkspace;
@@ -21,9 +24,14 @@ describe('@jscutlery/semver', () => {
2124
// Lib d is publishable and use a custom preset.
2225
testingWorkspace.generateLib('d', '--publishable --importPath=@proj/d');
2326
testingWorkspace.installSemver('d', '--preset=conventionalcommits');
27+
// macOS's BSD sed !== Linux's GNU sed
2428
testingWorkspace.exec(
2529
`
26-
sed -i 's/"preset": "conventionalcommits"/"preset": { "types": [ { "type": "feat", "section": "✨ Awesome features" } ] }/g' libs/d/project.json
30+
if [[ "$OSTYPE" == "darwin"* ]]; then
31+
sed -i '' 's/"preset": "conventionalcommits"/"preset": { "types": [ { "type": "feat", "section": "✨ Awesome features" } ] }/g' libs/d/project.json
32+
else
33+
sed -i 's/"preset": "conventionalcommits"/"preset": { "types": [ { "type": "feat", "section": "✨ Awesome features" } ] }/g' libs/d/project.json
34+
fi
2735
`,
2836
);
2937
testingWorkspace.exec(
@@ -403,6 +411,48 @@ describe('@jscutlery/semver', () => {
403411
});
404412
});
405413

414+
describe('when using commitParserOptions and libs/d changed (v0.1.0 => v0.2.0)', () => {
415+
beforeAll(async () => {
416+
const projectJson = JSON.parse(
417+
readFile(`${testingWorkspace.root}/libs/d/project.json`),
418+
);
419+
projectJson.targets['version'].options.commitParserOptions = {
420+
headerPattern:
421+
'^([A-Z]{3,}-\\d{1,5}):? (chore|build|ci|docs|feat|fix|perf|refactor|test)(?:\\(([\\w-]+)\\))?\\S* (.+)$',
422+
headerCorrespondence: ['ticketReference', 'type', 'scope', 'subject'],
423+
};
424+
await firstValueFrom(
425+
writeFile(
426+
`${testingWorkspace.root}/libs/d/project.json`,
427+
JSON.stringify(projectJson, null, 2),
428+
),
429+
);
430+
console.log(readFile(`${testingWorkspace.root}/libs/d/project.json`));
431+
testingWorkspace.exec(
432+
`
433+
echo feat >> libs/d/d.txt
434+
git add .
435+
git commit -m "TKT-1010: feat(d): 🚀 new feature"
436+
`,
437+
);
438+
testingWorkspace.runNx(`run d:version --noVerify`);
439+
});
440+
441+
it('should semver bump properly based on the custom commit header', () => {
442+
expect(
443+
readFile(`${testingWorkspace.root}/libs/d/package.json`),
444+
).toMatch(/"version": "0.2.0"/);
445+
});
446+
447+
it('should generate CHANGELOG.md properly', () => {
448+
expect(
449+
deterministicChangelog(
450+
readFile(`${testingWorkspace.root}/libs/d/CHANGELOG.md`),
451+
),
452+
).toMatchSnapshot('d-0.2.0');
453+
});
454+
});
455+
406456
describe('when libs/b changed with --skipCommit (v0.1.0 => v0.2.0)', () => {
407457
beforeAll(() => {
408458
testingWorkspace.exec(

packages/semver/src/executors/version/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ export default async function version(
138138
dependencyUpdates,
139139
skipCommit,
140140
skipStage,
141+
commitParserOptions,
141142
workspace: context.projectsConfigurations,
142143
};
143144

packages/semver/src/executors/version/schema.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,4 +47,5 @@ export interface WriteChangelogConfig {
4747
dryRun?: boolean;
4848
changelogPath: string;
4949
tagPrefix: string;
50+
commitParserOptions?: CommitParserOptions;
5051
}

packages/semver/src/executors/version/utils/changelog.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import type { Version } from '../version';
1515
import { diff } from './diff';
1616
import { readFile, readFileIfExists, writeFile } from './filesystem';
1717
import { PresetOpt } from '../schema';
18+
import { Options as CommitParserOptions } from 'conventional-commits-parser';
1819
export const defaultHeader = `# Changelog
1920
2021
This file was generated using [@jscutlery/semver](https://github.com/jscutlery/semver).
@@ -33,13 +34,15 @@ export function updateChangelog({
3334
newVersion,
3435
changelogHeader,
3536
tagPrefix,
37+
commitParserOptions,
3638
}: {
3739
projectRoot: string;
3840
dryRun: boolean;
3941
preset: PresetOpt;
4042
newVersion: string;
4143
tagPrefix: string;
4244
changelogHeader: string;
45+
commitParserOptions?: CommitParserOptions;
4346
}): Observable<string> {
4447
return defer(async () => {
4548
const changelogPath = getChangelogPath(projectRoot);
@@ -51,6 +54,7 @@ export function updateChangelog({
5154
projectRoot,
5255
preset,
5356
tagPrefix,
57+
commitParserOptions,
5458
},
5559
newVersion,
5660
);

packages/semver/src/executors/version/utils/conventional-commit.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,5 +19,6 @@ export function createConventionalCommitStream(
1919
{ version: newVersion },
2020
/// @ts-expect-error - Partially typed API
2121
{ path: config.projectRoot },
22+
config.commitParserOptions,
2223
);
2324
}

packages/semver/src/executors/version/utils/try-bump.spec.ts

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -68,11 +68,14 @@ describe('tryBump', () => {
6868
});
6969

7070
expect(mockConventionalRecommendedBump).toBeCalledTimes(1);
71-
expect(mockConventionalRecommendedBump).toBeCalledWith({
72-
path: '/libs/demo',
73-
preset: 'angular',
74-
tagPrefix: 'v',
75-
});
71+
expect(mockConventionalRecommendedBump).toBeCalledWith(
72+
{
73+
path: '/libs/demo',
74+
preset: 'angular',
75+
tagPrefix: 'v',
76+
},
77+
undefined,
78+
);
7679
});
7780

7881
it('should compute the next version based on last version, changes, and dependencies', async () => {
@@ -130,11 +133,14 @@ describe('tryBump', () => {
130133
});
131134

132135
expect(mockConventionalRecommendedBump).toBeCalledTimes(1);
133-
expect(mockConventionalRecommendedBump).toBeCalledWith({
134-
path: '/libs/demo',
135-
preset: 'angular',
136-
tagPrefix: 'v',
137-
});
136+
expect(mockConventionalRecommendedBump).toBeCalledWith(
137+
{
138+
path: '/libs/demo',
139+
preset: 'angular',
140+
tagPrefix: 'v',
141+
},
142+
undefined,
143+
);
138144
});
139145

140146
it('should use given type to calculate next version', async () => {

packages/semver/src/executors/version/utils/try-bump.ts

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,7 @@ export function tryBump({
158158
tagPrefix,
159159
releaseType,
160160
preid,
161+
commitParserOptions,
161162
}).pipe(map((version) => ({ type: 'project', version })));
162163

163164
const dependencyVersions$ = _getDependencyVersions({
@@ -233,22 +234,27 @@ export function _semverBump({
233234
tagPrefix,
234235
releaseType,
235236
preid,
237+
commitParserOptions,
236238
}: {
237239
since: string;
238240
preset: PresetOpt;
239241
projectRoot: string;
240242
tagPrefix: string;
241243
releaseType?: ReleaseIdentifier;
242244
preid?: string;
245+
commitParserOptions?: CommitParserOptions;
243246
}) {
244247
return defer(async () => {
245-
const recommended = await conventionalRecommendedBump({
246-
path: projectRoot,
247-
tagPrefix,
248-
...(typeof preset === 'string'
249-
? { preset }
250-
: { preset: preset.name ?? 'conventionalcommits', config: preset }),
251-
});
248+
const recommended = await conventionalRecommendedBump(
249+
{
250+
path: projectRoot,
251+
tagPrefix,
252+
...(typeof preset === 'string'
253+
? { preset }
254+
: { preset: preset.name ?? 'conventionalcommits', config: preset }),
255+
},
256+
commitParserOptions,
257+
);
252258

253259
let recommendedReleaseType: ReleaseIdentifier | undefined =
254260
recommended.releaseType;
@@ -368,6 +374,7 @@ export function _getDependencyVersions({
368374
preset,
369375
projectRoot,
370376
tagPrefix,
377+
commitParserOptions,
371378
}).pipe(
372379
map(
373380
(version) =>

packages/semver/src/executors/version/version.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { ProjectsConfigurations } from '@nx/devkit';
22
import { forkJoin, Observable, of } from 'rxjs';
33
import { concatMap, map } from 'rxjs/operators';
4+
import type { Options as CommitParserOptions } from 'conventional-commits-parser';
45
import { PresetOpt } from './schema';
56
import {
67
insertChangelogDependencyUpdates,
@@ -40,6 +41,7 @@ export interface CommonVersionOptions {
4041
dependencyUpdates: Version[];
4142
preset: PresetOpt;
4243
workspace: ProjectsConfigurations | undefined;
44+
commitParserOptions?: CommitParserOptions;
4345
}
4446

4547
export function versionWorkspace({

0 commit comments

Comments
 (0)