diff --git a/dev-infra/commit-message/cli.ts b/dev-infra/commit-message/cli.ts index e6e97e3a52..fb1581ef08 100644 --- a/dev-infra/commit-message/cli.ts +++ b/dev-infra/commit-message/cli.ts @@ -6,6 +6,7 @@ * found in the LICENSE file at https://angular.io/license */ import * as yargs from 'yargs'; +import {getUserConfig} from '../utils/config'; import {info} from '../utils/console'; @@ -78,11 +79,17 @@ export function buildCommitMessageParser(localYargs: yargs.Argv) { } return file; }, + }, + 'error': { + type: 'boolean', + description: + 'Whether invalid commit messages should be treated as failures rather than a warning', + default: !!getUserConfig().commitMessage?.errorOnInvalidMessage || !!process.env['CI'] } }, args => { const file = args.file || args['file-env-variable'] || '.git/COMMIT_EDITMSG'; - validateFile(file); + validateFile(file, args.error); }) .command( 'validate-range', 'Validate a range of commit messages', { diff --git a/dev-infra/commit-message/validate-file.ts b/dev-infra/commit-message/validate-file.ts index 830d33ab2d..87973835ca 100644 --- a/dev-infra/commit-message/validate-file.ts +++ b/dev-infra/commit-message/validate-file.ts @@ -8,29 +8,40 @@ import {readFileSync} from 'fs'; import {resolve} from 'path'; -import {getRepoBaseDir} from '../utils/config'; -import {error, green, info, red} from '../utils/console'; +import {getRepoBaseDir, getUserConfig} from '../utils/config'; +import {error, green, info, log, red, yellow} from '../utils/console'; import {deleteCommitMessageDraft, saveCommitMessageDraft} from './commit-message-draft'; import {printValidationErrors, validateCommitMessage} from './validate'; /** Validate commit message at the provided file path. */ -export function validateFile(filePath: string) { +export function validateFile(filePath: string, isErrorMode: boolean) { const commitMessage = readFileSync(resolve(getRepoBaseDir(), filePath), 'utf8'); const {valid, errors} = validateCommitMessage(commitMessage); if (valid) { info(`${green('√')} Valid commit message`); deleteCommitMessageDraft(filePath); + process.exitCode = 0; return; } - error(`${red('✘')} Invalid commit message`); - printValidationErrors(errors); - error('Aborting commit attempt due to invalid commit message.'); + /** Function used to print to the console log. */ + let printFn = isErrorMode ? error : log; + + printFn(`${isErrorMode ? red('✘') : yellow('!')} Invalid commit message`); + printValidationErrors(errors, printFn); + if (isErrorMode) { + printFn(red('Aborting commit attempt due to invalid commit message.')); + printFn( + red('Commit message aborted as failure rather than warning due to local configuration.')); + } else { + printFn(yellow('Before this commit can be merged into the upstream repository, it must be')); + printFn(yellow('amended to follow commit message guidelines.')); + } // On all invalid commit messages, the commit message should be saved as a draft to be // restored on the next commit attempt. saveCommitMessageDraft(filePath, commitMessage); - // If the validation did not return true, exit as a failure. - process.exit(1); + // Set the correct exit code based on if invalid commit message is an error. + process.exitCode = isErrorMode ? 1 : 0; }