Skip to content

Commit

Permalink
[FEATURE] Add failOnMatch option
Browse files Browse the repository at this point in the history
This option, when `"true"` will fail the checker when the given pattern
matches the commit message. This allows for a simpler kind check for
negative conditions such as "The commit message does not start with
'fixup'."

I rewrote some test cases here so that they were grouped into input
types. This allowed me to use the same inputs for both the default
settings and also the `failOnMatch` setting. Each of the "default" tests
are exactly the same as they were before, with the "via `failOnMatch`"
tests being the tests that were actually added.
  • Loading branch information
happycollision committed Feb 1, 2023
1 parent 4c06ad2 commit 085c42d
Show file tree
Hide file tree
Showing 6 changed files with 127 additions and 27 deletions.
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,15 @@ jobs:
excludeTitle: 'true' # optional: this excludes the title of a pull request
checkAllCommitMessages: 'true' # optional: this checks all commits associated with a pull request
accessToken: ${{ secrets.GITHUB_TOKEN }} # github access token is only required if checkAllCommitMessages is true
- name: Squash/Fixup Check
uses: gsactions/commit-message-checker@v2
with:
pattern: '^(fixup|squash)'
failOnMatch: 'true' # optional: this will fail the test if the pattern matches a commit message
error: Don't forget to squash/fixup your commits before merging
excludeDescription: 'true'
checkAllCommitMessages: 'true'
accessToken: ${{ secrets.GITHUB_TOKEN }}
- name: Check for Resolves / Fixes
uses: gsactions/commit-message-checker@v2
with:
Expand Down
108 changes: 90 additions & 18 deletions __tests__/commit-message-checker.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,51 +77,123 @@ describe('commit-message-checker tests', () => {
).rejects.toThrow('MESSAGES not defined.')
})

it('check fails single message', async () => {
describe('single message, without a match', () => {
const checkerArguments: ICheckerArguments = {
pattern: 'some-pattern',
flags: '',
error: 'some-error',
messages: ['some-message']
}
await expect(
commitMessageChecker.checkCommitMessages(checkerArguments)
).rejects.toThrow('some-error')

it('fails by default', async () => {
await expect(
commitMessageChecker.checkCommitMessages(checkerArguments)
).rejects.toThrow('some-error')
})

it('succeeds via `failOnMatch`', async () => {
await expect(
commitMessageChecker.checkCommitMessages({
...checkerArguments,
failOnMatch: true
})
).resolves.toBeUndefined()
})
})

it('check fails multiple messages', async () => {
describe('single message, with a match', () => {
const checkerArguments: ICheckerArguments = {
pattern: '.*',
flags: '',
error: 'some-error',
messages: ['some-message']
}

it('succeeds by default', async () => {
await expect(
commitMessageChecker.checkCommitMessages(checkerArguments)
).resolves.toBeUndefined()
})

it('fails via `failOnMatch`', async () => {
await expect(
commitMessageChecker.checkCommitMessages({
...checkerArguments,
failOnMatch: true
})
).rejects.toThrow('some-error')
})
})

describe('multiple messages, with a single match', () => {
const checkerArguments: ICheckerArguments = {
pattern: 'some-pattern',
flags: '',
error: 'some-error',
messages: ['some-message', 'some-pattern']
}
await expect(
commitMessageChecker.checkCommitMessages(checkerArguments)
).rejects.toThrow('some-error')

it('fails by default', async () => {
await expect(
commitMessageChecker.checkCommitMessages(checkerArguments)
).rejects.toThrow('some-error')
})

it('fails via `failOnMatch`', async () => {
await expect(
commitMessageChecker.checkCommitMessages({
...checkerArguments,
failOnMatch: true
})
).rejects.toThrow('some-error')
})
})

it('check succeeds on single message', async () => {
describe('multiple messages, without any match', () => {
const checkerArguments: ICheckerArguments = {
pattern: '.*',
pattern: 'some-pattern',
flags: '',
error: 'some-error',
messages: ['some-message']
messages: ['some-message', 'other-message']
}
await expect(
commitMessageChecker.checkCommitMessages(checkerArguments)
).resolves.toBeUndefined()

it('fails by default', async () => {
await expect(
commitMessageChecker.checkCommitMessages(checkerArguments)
).rejects.toThrow('some-error')
})

it('succeeds via `failOnMatch`', async () => {
await expect(
commitMessageChecker.checkCommitMessages({
...checkerArguments,
failOnMatch: true
})
).resolves.toBeUndefined()
})
})

it('check succeeds on multiple messages', async () => {
describe('multiple messages, all matching', () => {
const checkerArguments: ICheckerArguments = {
pattern: '.*',
flags: '',
error: 'some-error',
messages: ['some-message', 'other-message']
}
await expect(
commitMessageChecker.checkCommitMessages(checkerArguments)
).resolves.toBeUndefined()

it('succeeds by default', async () => {
await expect(
commitMessageChecker.checkCommitMessages(checkerArguments)
).resolves.toBeUndefined()
})

it('fails via `failOnMatch`', async () => {
await expect(
commitMessageChecker.checkCommitMessages({
...checkerArguments,
failOnMatch: true
})
).rejects.toThrow('some-error')
})
})
})
6 changes: 5 additions & 1 deletion action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,16 @@ inputs:
required: false
default: 'gm'
error:
description: 'A error message which will be returned in case of an error.'
description: 'An error message which will be returned in case of an error.'
required: true
excludeTitle:
description: 'Setting this input to true will exclude the Pull Request title from the check.'
required: false
default: 'false'
failOnMatch:
description: 'Setting this input to true will reverse the logic so that a positive match will fail the check.'
required: false
default: 'false'
excludeDescription:
description: 'Setting this input to true will exclude the Pull Request description from the check.'
required: false
Expand Down
12 changes: 8 additions & 4 deletions dist/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,9 +89,9 @@ function checkCommitMessages(args) {
}
// Check messages
let result = true;
core.info(`Checking commit messages against "${args.pattern}"...`);
core.info(`Checking commit messages ${args.failOnMatch ? 'do not ' : ''}match "${args.pattern}"...`);
for (const message of args.messages) {
if (checkMessage(message, args.pattern, args.flags)) {
if (checkMessage(message, args.pattern, args.flags, args.failOnMatch)) {
core.info(`- OK: "${message}"`);
}
else {
Expand All @@ -113,9 +113,10 @@ exports.checkCommitMessages = checkCommitMessages;
* @param pattern regex pattern for the check.
* @returns boolean
*/
function checkMessage(message, pattern, flags) {
function checkMessage(message, pattern, flags, failOnMatch) {
const regex = new RegExp(pattern, flags);
return regex.test(message);
const result = regex.test(message);
return failOnMatch ? !result : result;
}


Expand Down Expand Up @@ -200,6 +201,9 @@ function getInputs() {
// Get error message
result.error = core.getInput('error', { required: true });
core.debug(`error: ${result.error}`);
// Get failOnMatch
result.failOnMatch = core.getInput('failOnMatch') === 'true';
core.debug(`failOnMatch: ${result.failOnMatch}`);
// Get excludeTitle
const excludeTitleStr = core.getInput('excludeTitle');
core.debug(`excludeTitle: ${excludeTitleStr}`);
Expand Down
15 changes: 11 additions & 4 deletions src/commit-message-checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import * as core from '@actions/core'
*/
export interface ICheckerArguments {
pattern: string
failOnMatch?: boolean
flags: string
error: string
messages: string[]
Expand Down Expand Up @@ -66,10 +67,14 @@ export async function checkCommitMessages(
// Check messages
let result = true

core.info(`Checking commit messages against "${args.pattern}"...`)
core.info(
`Checking commit messages ${args.failOnMatch ? 'do not ' : ''}match "${
args.pattern
}"...`
)

for (const message of args.messages) {
if (checkMessage(message, args.pattern, args.flags)) {
if (checkMessage(message, args.pattern, args.flags, args.failOnMatch)) {
core.info(`- OK: "${message}"`)
} else {
core.info(`- failed: "${message}"`)
Expand All @@ -93,8 +98,10 @@ export async function checkCommitMessages(
function checkMessage(
message: string,
pattern: string,
flags: string
flags: string,
failOnMatch?: boolean
): boolean {
const regex = new RegExp(pattern, flags)
return regex.test(message)
const result = regex.test(message)
return failOnMatch ? !result : result
}
4 changes: 4 additions & 0 deletions src/input-helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@ export async function getInputs(): Promise<ICheckerArguments> {
result.error = core.getInput('error', {required: true})
core.debug(`error: ${result.error}`)

// Get failOnMatch
result.failOnMatch = core.getInput('failOnMatch') === 'true'
core.debug(`failOnMatch: ${result.failOnMatch}`)

// Get excludeTitle
const excludeTitleStr = core.getInput('excludeTitle')
core.debug(`excludeTitle: ${excludeTitleStr}`)
Expand Down

0 comments on commit 085c42d

Please sign in to comment.