Skip to content

Instantly share code, notes, and snippets.

@morozov
Last active January 17, 2024 00:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save morozov/31658cb3be7939ed8aab to your computer and use it in GitHub Desktop.
Save morozov/31658cb3be7939ed8aab to your computer and use it in GitHub Desktop.
A prepare-commit-msg hook which automatically composes commit message based on Jira task summary

Automatic commit message generator based on Jira task summary

Installation

  1. Make the script executable: chmod +x jira-prepare-commit-msg.py
  2. Copy or symlink it to the repository hooks directory: cp jira-prepare-commit-msg.py /path/to/repo/.git/hooks/prepare-commit-msg or to the global hooks directory: cp jira-prepare-commit-msg.py ~/.config/git/hooks/prepare-commit-msg.
  3. Specify the URL of your Jira server, your username and API token. Make sure HTTPS is used when possible, since the username and the token are sent unencrypted by means of Basic HTTP authentication.

Usage

In order to be correctly processed, the git branch should have the same name as the Jira issue number (e.g. JPA-71). The branches which have different name format are ignored.

Just type git commit, and automatically generated message will appear in the text editor of your choise:

morozov@viola:~/Projects/test (JPA-71)
↪ git commit

Retrieving JPA-71 summary from Jira...
---------------------------------------8<---------------------------------------
JPA-71: Criteria query: casting joined polymorphic entity

# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
# On branch JPA-71
# Your branch is ahead of 'origin/JPA-71' by 1 commit.
#   (use "git push" to publish your local commits)
#
# Changes to be committed:
#      new file:   test.txt
#
"~/Projects/test/.git/COMMIT_EDITMSG" 11L, 353C                 1,1          All
#!/usr/bin/env python3
import sys
import os
import subprocess
import requests
import re
from urllib.parse import quote
# Put your Jira username and API token to the .netrc file in your home directory
# https://confluence.atlassian.com/cloud/api-tokens-938839638.html
config = {
'url': 'https://jira.example.com/',
}
if len(sys.argv) < 2 or sys.argv[1] == '':
print(f"Usage: {os.path.basename(sys.argv[0])} <file> [<message>]", file=sys.stderr)
sys.exit(1)
# if a message is specified explicitly, exit
if len(sys.argv) >= 3 and sys.argv[2] != '':
sys.exit()
# determine the current Git branch
branch = subprocess.check_output(['git', 'rev-parse', '--abbrev-ref', 'HEAD'], universal_newlines=True).strip()
# check if it's a Jira issue
matches = re.match('^[A-Z]+-\\d+', branch)
if not matches:
sys.exit()
issue = matches.group(0)
url = f'{config["url"].rstrip("/")}/rest/api/latest/issue/{quote(issue, safe="")}?fields=summary'
print(f"Retrieving {issue} summary from Jira...", file=sys.stderr)
try:
response = requests.get(url)
response.raise_for_status()
except requests.exceptions.RequestException as e:
print(f"Unable to connect to server: {str(e)}", file=sys.stderr)
sys.exit(1)
data = response.json()
message = f"{issue}: {data['fields']['summary']}"
output_file = sys.argv[1]
if os.path.exists(output_file):
with open(output_file, 'r') as f:
message = message + '\n' + f.read()
with open(output_file, 'w') as f:
f.write(message)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment