Subversion pre-commit hook for Redmine

Close on the heels of my last post, here’s a little pre-commit script to help integrate Redmine issues with svn commits. The basic idea is that you can’t commit code to the repository without referencing a Redmine ticket. I searched the tubez for quite a while looking for something else like this. I found this forum post, but it had a bunch of shell syntax that didn’t work for me on Dreamhost.

I hereby disclaim that this was a quick hack for me and understand that there is probably a better way to do this. If, however, you’re not passionate about this sort of thing and just want something that works, it’ll do.

I’ve actually got 2 scripts for ya:
The SVN Hook
Copy and paste this first one into a file named ‘pre-commit’ (no file extension), and drop it into the hooks directory of your svn installation. This script will be called automatically by svn whenever someone tries to commit. All it really does is pass the submitted comment string on to our ruby script, featured below.


#!/bin/bash

REPOS="$1" 
TXN="$2" 

SVNLOOK=/usr/bin/svnlook

# change to the current working directory
cd `dirname $0`

# svnlook at the comments being submitted with the commit request
COMMENTS=$($SVNLOOK log -t "$TXN" "$REPOS")

# Holla out to a little ruby pre-commit script.  if it fails, exit with a return
#    code of 1, which means that errors occurred
/usr/bin/env ruby pre-commit.rb "$COMMENTS" || exit 1

A Ruby pre-commit script (pre-commit.rb)
Copy the following code and paste it into a file named ‘pre-commit.rb’. Drop the file into your svn/hooks directory alongside the pre-commit script created above.


#!/usr/bin/env ruby

comments = ARGV[0]

if /[a-zA-Z0-9]/ !~ comments
  raise "You must include a comment with your commit."
end

if /refs|fixes|closes\s#([0-9]+)/ !~ comments
  raise "You must reference a Redmine issue in your commit comments (e.g. 'refs #1234')."
end

issue_number = comments[/#([0-9]+)/][/([0-9]+)/]

# Change the username, password, hostname, and dbname in the following line
#    to match your settings
command_line_output = `/usr/bin/mysql -N -u your_mysql_username -pyour_password \
    -h mysql.yourhostname.com your_redmine_dbname -e \
    "SELECT COUNT(*) FROM issues I INNER JOIN issue_statuses S \
    ON S.id = I.status_id WHERE S.is_closed = 0 AND I.id = #{issue_number};"`

redmine_issue_open = command_line_output[0,1]
if '0' == redmine_issue_open
  raise "Issue ##{issue_number} is not in an open state."
end

Whew! That’s 2 techie posts in a row! I’ll try to come up with something more fun for everyone next time.

This entry was posted in Software Development and tagged , , , , .
Bookmark the permalink.
Follow any comments here with the RSS feed for this post.
Both comments and trackbacks are currently closed.

7 Comments