diff --git a/@commitlint/rules/src/header-breaking.test.ts b/@commitlint/rules/src/header-breaking.test.ts new file mode 100644 index 0000000000..e34d8c3663 --- /dev/null +++ b/@commitlint/rules/src/header-breaking.test.ts @@ -0,0 +1,24 @@ +import parse from '@commitlint/parse'; +import {headerBreaking} from './header-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] = headerBreaking(await parsed.empty); + const expected = true; + expect(actual).toEqual(expected); +}); + +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 af8ea6a544..9b34a9dd05 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 {headerBreaking} from './header-breaking'; import {subjectCase} from './subject-case'; import {subjectEmpty} from './subject-empty'; import {subjectFullStop} from './subject-full-stop'; @@ -47,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,