From c3bd59ddca0504a77076f30768ad038f6a240ff8 Mon Sep 17 00:00:00 2001 From: Anatoli Babenia Date: Thu, 4 Jan 2024 01:47:16 +0000 Subject: [PATCH 1/2] feat: add rule for `BREAKING CHANGE:` in subject `BREAKING CHANGE:` is a footer thing Fixed https://github.com/conventional-changelog/commitlint/issues/3810 --- @commitlint/rules/src/index.ts | 2 ++ .../rules/src/subject-breaking.test.ts | 24 +++++++++++++++++++ @commitlint/rules/src/subject-breaking.ts | 7 ++++++ 3 files changed, 33 insertions(+) create mode 100644 @commitlint/rules/src/subject-breaking.test.ts create mode 100644 @commitlint/rules/src/subject-breaking.ts diff --git a/@commitlint/rules/src/index.ts b/@commitlint/rules/src/index.ts index af8ea6a544..a595fa0b17 100644 --- a/@commitlint/rules/src/index.ts +++ b/@commitlint/rules/src/index.ts @@ -21,6 +21,7 @@ import {scopeEnum} from './scope-enum'; import {scopeMaxLength} from './scope-max-length'; import {scopeMinLength} from './scope-min-length'; import {signedOffBy} from './signed-off-by'; +import {subjectBreaking} from './subject-breaking'; import {subjectCase} from './subject-case'; import {subjectEmpty} from './subject-empty'; import {subjectFullStop} from './subject-full-stop'; @@ -58,6 +59,7 @@ export default { 'scope-max-length': scopeMaxLength, 'scope-min-length': scopeMinLength, 'signed-off-by': signedOffBy, + 'subject-breaking': subjectBreaking, 'subject-case': subjectCase, 'subject-empty': subjectEmpty, 'subject-full-stop': subjectFullStop, diff --git a/@commitlint/rules/src/subject-breaking.test.ts b/@commitlint/rules/src/subject-breaking.test.ts new file mode 100644 index 0000000000..4888207bad --- /dev/null +++ b/@commitlint/rules/src/subject-breaking.test.ts @@ -0,0 +1,24 @@ +import parse from '@commitlint/parse'; +import {subjectBreaking} from './subject-breaking'; + +const messages = { + empty: 'test: \nbody', + filled: 'BREAKING CHANGE: this one', +}; + +const parsed = { + empty: parse(messages.empty), + filled: parse(messages.filled), +}; + +test('without subject should succeed', async () => { + const [actual] = subjectBreaking(await parsed.empty); + const expected = true; + expect(actual).toEqual(expected); +}); + +test('subject fail with BREAKING CHANGE:', async () => { + const [actual] = subjectBreaking(await parsed.filled); + const expected = false; + expect(actual).toEqual(expected); +}); diff --git a/@commitlint/rules/src/subject-breaking.ts b/@commitlint/rules/src/subject-breaking.ts new file mode 100644 index 0000000000..6d507f1d7e --- /dev/null +++ b/@commitlint/rules/src/subject-breaking.ts @@ -0,0 +1,7 @@ +import {SyncRule} from '@commitlint/types'; + +export const subjectBreaking: SyncRule = (parsed) => { + const result = parsed.subject?.startsWith('BREAKING CHANGE:'); + + return [!result, 'move BREAKING CHANGE: to footer']; +}; From f1a214f3f750a991c849011534559a64ef9ef924 Mon Sep 17 00:00:00 2001 From: Anatoli Babenia Date: Fri, 5 Jan 2024 09:35:02 +0000 Subject: [PATCH 2/2] fix: check `header` not `subject` --- .../{subject-breaking.test.ts => header-breaking.test.ts} | 8 ++++---- @commitlint/rules/src/header-breaking.ts | 7 +++++++ @commitlint/rules/src/index.ts | 4 ++-- @commitlint/rules/src/subject-breaking.ts | 7 ------- 4 files changed, 13 insertions(+), 13 deletions(-) rename @commitlint/rules/src/{subject-breaking.test.ts => header-breaking.test.ts} (63%) create mode 100644 @commitlint/rules/src/header-breaking.ts delete mode 100644 @commitlint/rules/src/subject-breaking.ts diff --git a/@commitlint/rules/src/subject-breaking.test.ts b/@commitlint/rules/src/header-breaking.test.ts similarity index 63% rename from @commitlint/rules/src/subject-breaking.test.ts rename to @commitlint/rules/src/header-breaking.test.ts index 4888207bad..e34d8c3663 100644 --- a/@commitlint/rules/src/subject-breaking.test.ts +++ b/@commitlint/rules/src/header-breaking.test.ts @@ -1,5 +1,5 @@ import parse from '@commitlint/parse'; -import {subjectBreaking} from './subject-breaking'; +import {headerBreaking} from './header-breaking'; const messages = { empty: 'test: \nbody', @@ -12,13 +12,13 @@ const parsed = { }; test('without subject should succeed', async () => { - const [actual] = subjectBreaking(await parsed.empty); + const [actual] = headerBreaking(await parsed.empty); const expected = true; expect(actual).toEqual(expected); }); -test('subject fail with BREAKING CHANGE:', async () => { - const [actual] = subjectBreaking(await parsed.filled); +test('BREAKING CHANGE: in header should fail', async () => { + const [actual] = headerBreaking(await parsed.filled); const expected = false; expect(actual).toEqual(expected); }); diff --git a/@commitlint/rules/src/header-breaking.ts b/@commitlint/rules/src/header-breaking.ts new file mode 100644 index 0000000000..e188e4ed3d --- /dev/null +++ b/@commitlint/rules/src/header-breaking.ts @@ -0,0 +1,7 @@ +import {SyncRule} from '@commitlint/types'; + +export const headerBreaking: SyncRule = (parsed) => { + const result = parsed.header?.startsWith('BREAKING CHANGE:'); + + return [!result, 'move BREAKING CHANGE: to footer']; +}; diff --git a/@commitlint/rules/src/index.ts b/@commitlint/rules/src/index.ts index a595fa0b17..9b34a9dd05 100644 --- a/@commitlint/rules/src/index.ts +++ b/@commitlint/rules/src/index.ts @@ -21,7 +21,7 @@ import {scopeEnum} from './scope-enum'; import {scopeMaxLength} from './scope-max-length'; import {scopeMinLength} from './scope-min-length'; import {signedOffBy} from './signed-off-by'; -import {subjectBreaking} from './subject-breaking'; +import {headerBreaking} from './header-breaking'; import {subjectCase} from './subject-case'; import {subjectEmpty} from './subject-empty'; import {subjectFullStop} from './subject-full-stop'; @@ -48,6 +48,7 @@ export default { 'footer-max-length': footerMaxLength, 'footer-max-line-length': footerMaxLineLength, 'footer-min-length': footerMinLength, + 'header-breaking': headerBreaking, 'header-case': headerCase, 'header-full-stop': headerFullStop, 'header-max-length': headerMaxLength, @@ -59,7 +60,6 @@ export default { 'scope-max-length': scopeMaxLength, 'scope-min-length': scopeMinLength, 'signed-off-by': signedOffBy, - 'subject-breaking': subjectBreaking, 'subject-case': subjectCase, 'subject-empty': subjectEmpty, 'subject-full-stop': subjectFullStop, diff --git a/@commitlint/rules/src/subject-breaking.ts b/@commitlint/rules/src/subject-breaking.ts deleted file mode 100644 index 6d507f1d7e..0000000000 --- a/@commitlint/rules/src/subject-breaking.ts +++ /dev/null @@ -1,7 +0,0 @@ -import {SyncRule} from '@commitlint/types'; - -export const subjectBreaking: SyncRule = (parsed) => { - const result = parsed.subject?.startsWith('BREAKING CHANGE:'); - - return [!result, 'move BREAKING CHANGE: to footer']; -};