Git commit message & Redmine
In our company we use Redmine and Git in our daily activities (yes,we coding every day :) ). We also like referencing Redmine issue in our commit message, eg:
git commit -m "refs #123: Lorem ipsum message"
and this is really usefull to connect code to issue.
Git have opportunity to use hooks to executing check during operation (commit, push, ...) so we can use a specific hook (commit-msg) to ensure our commit message are correctly conected to Redmine.
I create a simple script that you can use to "block" commit that don't match a specific pattern or refereicing a wrong issue in Redmine, eg:
git commit -m "refs 1234566890: Lorem ipsum"
Commit need to be "[refs|fix] #ID: message"
or
git commit -m "refs #1234: Lorem ipsum"
You are working as user 3 but issue is not assigned to you
Requirement
You need to have git and bash on your machine, python is also required but I'm working to remove this dependence.
You need to enable REST WS in your Redmine, this is possible from admin / settings / autentication .
You need to find your API key in your profile page in Redmine ( https://redmine.yourcompany.com/my/account ).
Setup
You need to copy the following code in commit-msg hook. The hook file will be in yourepo/.git/hooks/commit-msg, and must be executable:
touch $YOUR_REPO/.git/hooks/commit-msg
chmod +x $YOUR_REPO/.git/hooks/commit-msg
edit $YOUR_REPO/.git/hooks/commit-msg
Paste the following code:
#!/bin/bash
regex="^(refs|fix)\s\#[0-9]+\:"
var=`head -n 1 $1`
function info {
echo >&2 $1
}
function debug {
debug=false
if $debug
then
echo >&2 $1
fi
}
function get_json {
python -c "import sys;import json;j=json.loads(sys.stdin.read());print str(j$1);"
}
function redmine_json {
redmine_host=$(git config redmine.host)
redmine_apikey=$(git config redmine.apikey)
curl --silent -k -H "Content-Type: application/json" -X GET -H "X-Redmine-API-Key: $redmine_apikey" "$redmine_host/$1"
}
if [[ "$var" =~ $regex ]]
then
debug "Commit message: OK"
else
# Define format message forfirst line in commit message
info "Commit need to be \"[refs|fix] #ID: message\""
exit 1
fi
issue_id=`echo $var | sed 's/\(refs\|fix\)\ \#\([0-9]*\).*/\2/'`
issue=`redmine_json "issues/$issue_id\.json"`
if [[ "$issue" != " " ]]
then
debug "Issue exist: OK"
else
info "Issue $issue_id don't exist"
exit 2;
fi
user=`redmine_json "users/current.json"`
user_id=`echo $user | get_json "['user']['id']"`
assigner_id=`echo $issue | get_json "['issue']['assigned_to']['id']"`
if [[ $user_id == $assigner_id ]]
then
debug "Assigner: OK"
else
info "You are working as user $user_id but issue is not assigned to you"
exit 3;
fi
redmine_host=$(git config redmine.host)
echo ""
echo "Issue ==========================="
echo " refs: $redmine_host/issues/$issue_id"
echo " number: #"`echo $issue | get_json "['issue']['id']"`
echo " priority: "`echo $issue | get_json "['issue']['priority']['name']"`
echo " create from: "`echo $issue | get_json "['issue']['author']['name']"`
echo " assigned to: "`echo $issue | get_json "['issue']['assigned_to']['name']"`
echo ""
More info in the script are in the more info section.
Configure
You also need to configure git to find redmine instance:
git config redmine.host https://redmine.yourcompany.com
git config redmine.apikey 1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef
now if you try to writing a wrong commit message recive an error and the commit will stop. If your commit message is ok, you can see:
Issue ===========================
refs: https://redmine.yourcompany.com/issues/1234
number: #1234
priority: Normal
create from: Issue Creator
assigned to: Your Name
Sometime you need to commit without referencing an issue or referencing an issue that is not assigned to you, you can skip control using --no-verify
parameter.
More info
Our script is composed from two main function:
function get_json {
python -c "import sys;import json;j=json.loads(sys.stdin.read());print str(j$1);"
}
This function parse input string (from stdin)9 asjson and and extract specified item, eg:
echo "{'test': {'some': 1,'element':3}}" | get_json '["test"]["element"]'
return 3.
The second function is
function redmine_json {
redmine_host=$(git config redmine.host)
redmine_apikey=$(git config redmine.apikey)
curl --silent -k -H "Content-Type: application/json" -X GET -H "X-Redmine-API-Key: $redmine_apikey" "$redmine_host/$1"
}
This make a request to redmine using API Key and host specified in git config and return response as JSON string.
redmine_json "users/current.json"
the other element of script are some simple check about data consistence.
Written by Marco Vito Moscaritolo
Related protips
2 Responses
Hello,
Great Article!
But looks like the following portion will always succeed because you will get a 404 response even if the issue is not found. Am I missing something?
if [[ "$issue" != " " ]]
then
debug "Issue exist: OK"
else
info "Issue $issue_id don't exist"
exit 2;
fi
If your issue is not found hook exit without complete command (exit 2)