diff --git a/ng-dev/commit-message/validate.spec.ts b/ng-dev/commit-message/validate.spec.ts index a2b8444c6..703afbf43 100644 --- a/ng-dev/commit-message/validate.spec.ts +++ b/ng-dev/commit-message/validate.spec.ts @@ -266,6 +266,33 @@ describe('validate-commit-message.js', () => { ); }); }); + + describe('with `disallowFixup`', () => { + it('when true should fail', async () => { + const msg = 'fixup! foo'; + + expectValidationResult( + await validateCommitMessage(msg, { + disallowFixup: true, + nonFixupCommitHeaders: ['foo', 'bar', 'baz'], + }), + INVALID, + ['The commit must be manually fixed-up into the target commit as fixup commits are disallowed'], + ); + }); + + it('when false should pass', async () => { + const msg = 'fixup! foo'; + + expectValidationResult( + await validateCommitMessage(msg, { + disallowFixup: false, + nonFixupCommitHeaders: ['foo', 'bar', 'baz'], + }), + VALID, + ); + }); + }); }); describe('minBodyLength', () => { diff --git a/ng-dev/commit-message/validate.ts b/ng-dev/commit-message/validate.ts index 40f742fbf..feda03d37 100644 --- a/ng-dev/commit-message/validate.ts +++ b/ng-dev/commit-message/validate.ts @@ -15,6 +15,7 @@ import {Commit, parseCommitMessage} from './parse.js'; /** Options for commit message validation. */ export interface ValidateCommitMessageOptions { disallowSquash?: boolean; + disallowFixup?: boolean; nonFixupCommitHeaders?: string[]; } @@ -90,6 +91,14 @@ export async function validateCommitMessage( // stripping the `fixup! ` prefix), otherwise we assume this verification will happen in another // check. if (commit.isFixup) { + if (options.disallowFixup) { + errors.push( + 'The commit must be manually fixed-up into the target commit as fixup commits are disallowed', + ); + + return false; + } + if (options.nonFixupCommitHeaders && !options.nonFixupCommitHeaders.includes(commit.header)) { errors.push( 'Unable to find match for fixup commit among prior commits: ' +