Skip to content

Commit fc94f2d

Browse files
committed
fix: prevent false-positive major bumps from breaking change detection
1 parent 26b8c6b commit fc94f2d

4 files changed

Lines changed: 55 additions & 3 deletions

File tree

packages/shipjs-lib/src/lib/const.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,6 @@ export const GIT_COMMIT_PREFIX_PATCH = new Set([
1111

1212
export const GIT_COMMIT_PREFIX_MINOR = new Set(['feat']);
1313

14-
export const GIT_COMMIT_BREAKING_CHANGE = 'BREAKING CHANGE';
14+
export const GIT_COMMIT_BREAKING_CHANGE = /^BREAKING[ -]CHANGE\s*:/;
1515

1616
export const RELEASE_BRANCH = 'releases';

packages/shipjs-lib/src/lib/util/__tests__/getNextVersion.spec.js

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,55 @@ describe('getNextVersionFromCommitMessages', () => {
9797
expect(actual).toBe('1.0.0');
9898
});
9999

100+
it('detects major from BREAKING-CHANGE with hyphen', () => {
101+
const version = '1.2.3';
102+
const titles = 'feat: abc';
103+
const bodies = 'BREAKING-CHANGE: this also breaks things.';
104+
const { version: actual } = getNextVersionFromCommitMessages(
105+
version,
106+
titles,
107+
bodies
108+
);
109+
expect(actual).toBe('2.0.0');
110+
});
111+
112+
it('does not trigger major from prose mentioning breaking changes', () => {
113+
const version = '1.2.3';
114+
const titles = 'feat: upgrade storybook';
115+
const bodies =
116+
'This PR includes breaking changes around package consolidation.';
117+
const { version: actual } = getNextVersionFromCommitMessages(
118+
version,
119+
titles,
120+
bodies
121+
);
122+
expect(actual).toBe('1.3.0');
123+
});
124+
125+
it('detects major from ! suffix in title', () => {
126+
const version = '1.2.3';
127+
const titles = 'feat!: remove deprecated API';
128+
const bodies = '';
129+
const { version: actual } = getNextVersionFromCommitMessages(
130+
version,
131+
titles,
132+
bodies
133+
);
134+
expect(actual).toBe('2.0.0');
135+
});
136+
137+
it('detects major from scoped ! suffix in title', () => {
138+
const version = '1.2.3';
139+
const titles = 'fix(auth)!: change token format';
140+
const bodies = '';
141+
const { version: actual } = getNextVersionFromCommitMessages(
142+
version,
143+
titles,
144+
bodies
145+
);
146+
expect(actual).toBe('2.0.0');
147+
});
148+
100149
it('gets a null with no commit messages', () => {
101150
const version = '0.0.1';
102151
const titles = '';

packages/shipjs-lib/src/lib/util/getCommitNumbersPerType.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ export default function getCommitNumbersPerType(commitTitles) {
1616
ignoredMessages.push(title);
1717
return;
1818
}
19-
const prefix = match[1].toLowerCase();
19+
const prefix = match[1].replace(/!$/, '').toLowerCase();
2020
if (
2121
GIT_COMMIT_PREFIX_PATCH.has(prefix) ||
2222
GIT_COMMIT_PREFIX_MINOR.has(prefix)

packages/shipjs-lib/src/lib/util/getNextVersion.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,13 @@ export function getNextVersionFromCommitMessages(version, titles, bodies) {
1818
bodies
1919
.toUpperCase()
2020
.split('\n')
21-
.some((line) => line.startsWith(GIT_COMMIT_BREAKING_CHANGE))
21+
.some((line) => GIT_COMMIT_BREAKING_CHANGE.test(line.trim()))
2222
) {
2323
return { version: inc(version, 'major') };
2424
}
25+
if (titles.split('\n').some((line) => /^\w+(\(.*?\))?!:/.test(line.trim()))) {
26+
return { version: inc(version, 'major') };
27+
}
2528
const { numbers, ignoredMessages } = getCommitNumbersPerType(titles);
2629
const minor = Array.from(GIT_COMMIT_PREFIX_MINOR).some(
2730
(prefix) => numbers[prefix] > 0

0 commit comments

Comments
 (0)