.github/hooks/commit-msg
#!/bin/bash
# Retrieve the commit message
commit_msg_file=$1
commit_msg=$(cat $commit_msg_file)
# Ignore merge commits
if [[ $commit_msg == "Merge branch"* ]]; then
exit 0
fi
# Regular expressions for each commit type
feat_regex='^feat(\([a-zA-Z0-9]+\))?!?: .+'
fix_regex='^fix(\([a-zA-Z0-9]+\))?!?: .+'
breaking_change_footer_regex='^BREAKING( |-)CHANGE: .+'
valid_types='^(feat|fix|docs|style|refactor|perf|test|build|ci|chore)(\([a-zA-Z0-9]+\))?!?: .+'
# Verify the commit type
if [[ !($commit_msg =~ $valid_types) ]]; then
echo "Error: commit message must be valid <type>(<context>): <message>"
echo "$commit_msg"
exit 1
fi
# If there is a BREAKING CHANGE, check if it's valid
if [[ $commit_msg == *"BREAKING CHANGE"* || $commit_msg == *"BREAKING-CHANGE"* ]]; then
if [[ $commit_msg =~ $breaking_change_footer_regex ]]; then
echo "Commit with valid breaking change detected"
else
echo "Error: invalid 'BREAKING CHANGE:' or 'BREAKING-CHANGE:' in the commit message"
exit 1
fi
fi
# Verify 'feat' or 'fix'
if [[ ($commit_msg =~ $feat_regex) || ($commit_msg =~ $fix_regex) ]]; then
echo "Commit accepted"
else
echo "Error: for 'feat' and 'fix' types, a description must follow the ':' and space"
exit 1
fi
exit 0