diff --git a/.github/hooks/commit-msg b/.github/hooks/commit-msg new file mode 100755 index 0000000..581418b --- /dev/null +++ b/.github/hooks/commit-msg @@ -0,0 +1,17 @@ +#!/bin/sh + +# Define the regular expression for Jira ticket numbers +REGEX="MAT-[0-9]+\s.*" + +# Extract the commit message +MESSAGE=$(cat "$1") + +# Check if the message contains a valid Jira ticket number +if [[ ! $MESSAGE =~ $REGEX ]]; then + echo "ERROR: Commit message must contain a valid Jira ticket number (e.g., ABC-123)" + echo "Please follow the format: : " + exit 1 +fi + +# Allow the commit if the check passes +exit 0 diff --git a/.github/workflows/commit_message_validation.yml b/.github/workflows/commit_message_validation.yml new file mode 100644 index 0000000..62bcc34 --- /dev/null +++ b/.github/workflows/commit_message_validation.yml @@ -0,0 +1,63 @@ +name: validate git commit messages + +on: + pull_request: + branches: [ main, develop ] + +jobs: + commit_message_validation: + name: validate git commit messages + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 + ref: '${{ github.event.pull_request.base.ref }}' + + - name: Execute message validation + run: | + # Checkout branch + git checkout -q ${{ github.event.pull_request.head.ref }} + # Set variables + BASE_BRANCH=${{ github.event.pull_request.base.ref }} + msg_regex='MAT-[0-9]+\s.*' + # This list permits some commits + commit_static_permit_list="(^Merge pull request \#)|(^Merge remote-tracking\s.*)|(^Merge branch)|(^Revert \")" + # Initialize invalidCommit as false, will be set to true by any invalid commits + invalidCommit=false + CURRENT_BRANCH=$(git branch | grep ^\* | cut -d "*" -f 2 | cut -d " " -f 2) + # Find hash of commit most common ancestor, e.g. where branch began + BRANCH_MERGE_BASE=$(git merge-base ${BASE_BRANCH} ${CURRENT_BRANCH}) + # Find all commits since common ancestor + BRANCH_COMMITS=$(git rev-list ${BRANCH_MERGE_BASE}..HEAD) + # Check every commit message since ancestor for regex match + for commit in $BRANCH_COMMITS; do + # Check if ticket in static permit-list for non-Jira commit_sha + if $(git log --max-count=1 --format=%B $commit | grep -iqE "$commit_static_permit_list"); then + : #If commit matches regex, commit is valid, do nothing + elif git log --max-count=1 --format=%B $commit | tr '[a-z]' '[A-Z]' | grep -iqE "$msg_regex"; then + : #If commit matches regex, commit is valid, do nothing + else + # If commit doesn't match regex, commit isn't valid, print commit info + echo "************" + printf "Invalid commit message: \"%s\" and hash: %s\n" "$(git log --max-count=1 --format=%B $commit)" "$commit" + echo "************" + # Set this variable to trigger rejection if any commit fails regex + invalidCommit=true + fi + done + + # If any commit are invalid, print reject message + if [ "$invalidCommit" == true ]; then + echo "Your push was rejected because at least one commit message on this branch is invalid" + echo "Please fix the commit message(s) and push again." + echo "https://help.github.com/en/articles/changing-a-commit-message" + echo "************" + exit 1 + elif [ "$invalidCommit" == false ]; then + echo "************" + echo "All commits are valid" + echo "************" + exit 0 + fi \ No newline at end of file