Require Commits to Link to Jira


This document describes how to add pre-receive hook script for validating that all incoming commits contain reference to Jira ID in a commit message when branch name contains reference to Jira ID.

You can extend script to implement any policy which is required by your workflow.

Setting up Hook #

Put the following script under the
<bitbucket-home-dir>/external-hooks/require-jira-id path on your Bitbucket Server installation.

If you use Bitbucket Data Center, put script under the
<bitbucket-home-dir>/shared/external-hooks/require-jira-id path.

Make sure it has the executable flag set (e.g. run chmod +x <path-to-file>).

#!/bin/bash

pattern='\b([a-zA-Z]+)+-[0-9]+\b'

failed=false

z40="0000000000000000000000000000000000000000"
while read from_ref to_ref ref_name; do
    if [[ "$to_ref" == "$z40" ]]; then
        # do not validate case of branch removing
        continue
    fi

    if ! grep -Pq "$pattern" <<< "$ref_name"; then
        # ignore branch which does not match Jira ID
        continue
    fi

    if [[ "$from_ref" == "$z40" ]]; then
        # if it is a new branch then check all branch related commits
        boundaries=($(git rev-list --simplify-by-decoration -2 "$to_ref"))
        commits=($(git rev-list "${boundaries[0]}".."$to_ref"))
    else
        # if it is existing branch then check only new commits
        commits=($(git rev-list "$from_ref".."$to_ref"))
    fi

    for commit in "${commits[@]}"; do
        message=$(git show -s --format=%B "$commit")
        if ! grep -Pq "$pattern" <<< "$message"; then
            if ! $failed; then
                # add first newline
                echo >&2
            fi

            echo "${commit:0:8} commit does not contain a Jira ID" >&2

            failed=true
        fi
    done
done

if $failed; then
    echo >&2
    exit 1
fi

Configuration #

Navigate to your repository page → Repository settings → Hooks, and enable the External Pre Receive Hook with the following parameters:

  • Type: Pre Receive
  • Executable: require-jira-id
  • Safe mode:
  • Positional arguments: leave it empty

After these actions are done, you can test that hooks works by pushing some commits into your repo and observing output:

Further Ideas #

  • validate project slug in incoming Jira ID by passing valid values in Positional arguments to script and then constructing pattern to restrict it to valid slugs only;
  • validate that specified Jira ID is present in the Jira by requesting Jira API directly from the script.

Got Some Questions? #

We will be glad to help to adapt configuration for your workflow.

Join our Slack or file an issue on GitHub: