Easily extend post-commit hook in Subversion using NAnt – email anyone?

There are several scripts floating around the Net regarding publishing an email to the development list every time someone commits a revision to Subversion.

In other cases, you may want to post the commit log entry directly to your project tracking system, such as trac, Rally, Gemini, Mingle, etc.  Anything under the sun can be coded into a post-commit action with Subversion.

Here’s how it works.  Here is how to send post commit email from Subversion while running on Windows:

In your subversion repository, there is a hooks folder.  This contains some template files for you.  On a Windows system, you’ll want a file called post-commit.bat.  This batch command will be run immediately after Subversion commits a transactional revision to the repository.  You can do work on other events, but I’ll focus on post-commit for this post.

Here is my post-commit.bat file that will call NAnt (which is placed inside the hooks folder for simplicity):

pushd .
cd DRIVELETTER:svnrepositoriesrepositorynamehooks
nantnant.exe -buildfile:postcommitemail.build -D:path.repository=%1 -D:revision=%2 > lastpostcommitrun.txt
popd

Notice how we are merely calling nant.exe.  The rest of the interesting work is done by NAnt.  Now that we are within NAnt, we can script out any action we might need.  In this case, I’m going to use some SVN command line tools to build up a simple email that with send developers what was included in the last commit:

<?xml version="1.0" encoding="utf-8"?>
<project name="commit" default="build" xmlns="http://nant.sf.net/release/0.85/nant.xsd">
    <target name="build">

        <exec program="svnlook" commandline="author ${path.repository} -r ${revision}" output="author.txt"/>        
        <exec program="svnlook" commandline="info ${path.repository} -r ${revision}" output="message.txt"/>
        <echo message=" " file="message.txt" append="true"/>
        <exec program="svnlook" commandline="changed ${path.repository} -r ${revision}" output="message.txt" append="true" />
        <exec program="svnlook" commandline="diff ${path.repository} -r ${revision} --no-diff-deleted --no-diff-added" output="message.txt" append="true"/>
        
        <loadfile file="author.txt" property="author"/>
        <loadfile file="message.txt" property="message"/>
        <mail tolist=jeffrey@mydomain.com
            from=build@mydomain.com 
            subject="SVN ${path.repository} - ${author}" 
            message="${message}" 
            mailhost="smtp.mydomain.com"/>
    </target>

</project>

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

That’s all it takes.  I can write anything I need to in order to perform custom actions when things happen with my Subversion repository.  In this case, I’m sending email to a list, and the email contains the last commit.

8 comments

  1. You could just let CC.Net do this as well. It might be easier.

  2. @Jeremy,
    You absolutely can, but it’s a bit more work with CCNet. CCNet offers the build notification email very nicely, and we definitely use that, but the nice diff of what the commit contains requires a bit more work. I’m giving email as an example because there are lots of folks searching for a way to send post-commit emails from Subversion on Windows, and I’m sure only a fraction of them are using CCNet.

    Once you get into NAnt, the possibilities are endless.

  3. Gary Brunton

    You may want to take a look at a product called Scmbug.

    From the website:
    scmbug integrates software configuration management (SCM) with bug-tracking. It aims to solve the integration problem once and for all. It will glue any source code version control system (such as CVS/CVSNT, Subversion, Git) with any bug-tracking system (such as Bugzilla, Mantis, Request Tracker, Test Director).

    I use it and it works great. It is completely configurable and also handles post-commit emails (as well as many other things such as pre-commit requirements).

    http://www.mkgnu.net/?q=scmbug

  4. Great timing! Setting up the commit emails was first on my todo list today.

    Tweaked your .bat file a little so that I could pass in a project name which gets placed in subject instead of the repo folder name.

    I added
    -D:ProjectName=”ProjectName”
    to the call to nant.exe before the
    > lastpostcommitrun.txt

    Then I changed the subject in the email that the build file sends to
    subject=”SVN – ${ProjectName} – ${revision} – ${author}”

    Works nicely! Thanks!

    PS – I noticed you didn’t put quotes around either of the email addresses in your task. I got an unexpected token error when I tried to run that build file.

  5. Looks pretty useful. Did you realise that PUSHD will take care of the CD for you, so you could just write:

    pushd DRIVELETTER:svnrepositoriesrepositorynamehooks
    nantnant.exe -buildfile:postcommitemail.build -D:path.repository=%1 -D:revision=%2 > lastpostcommitrun.txt
    popd

  6. BTW – your comments form doesn’t work with Javascript disabled.

  7. Mike

    I have created a Subversion hook tool that allows you to configure both pre- and post-commit e-mail messages on a per-repository folder level. For the pre-commit, you can enforce commit message regular expressions to make sure that you have “good” commit messages. If will also tie into a Bugzilla instance to ensure that the bug you’re committing against is open and valid. It can also lock down specific repro paths and file types. The post commit allows you to send nicely formatted e-mails out to whomever you choose.
    You can check out the details at http://mckechney.com/SubversionNotifyForWindows and then download it from SourceForge.net

  8. Have you had a look at Captain Hook [https://sourceforge.net/projects/captainhook/] which is a simple plugin framework for writing Subversion hooks using .NET written by Phil Haack.

Comments are closed.