Using Node.js and coffee-script to send subversion commit notification emails

A small team at work is using a Subversion server for managing the code of various automation scripts and other things. The server is a Windows server and has the CollabNet flavor of Subversion installed on it with it running a Windows service exposing the SVN protocol for clients to connect to. I had to start doing some occasional stuff with these repositories and thought it would be useful to have it send out an email notification whenever someone committed something.

Subversion comes with a hooks feature that makes setting up a script to send this sort of a notification fairly easy. There are examples in the “hooks” sub-directory of any repository. After doing a very brief search on the internet, I decided to skip doing the typical python thing that I was finding, and instead I rolled my own using Node.js and wrote it in CoffeeScript. I chose those tools because I enjoy working with them, they were already installed, and it would be easy!

The post-commit hook

Since I set this up on a Windows server, I’m going to be writing this example based on Windows. The first thing that you will need is a DOS batch file that will be called by subversion when a commit is completed. The post-commit.bat file can just be placed in the “hooks” sub-directory. You will need to edit the path that it changes to (CD) so that it can navigate to where you place the commit-email.coffee script at. It switches to that directory and then executes the CoffeeScript’s coffee command to directly run the CoffeeScript file; no prior-compiling needed.

A DOS batch file that invokes the CoffeeScript coffee command to execute the script that sends a SVN commit notification email.

Used in a SVN hook to invoke the CoffeeScript coffee command and execute a post-commit hook script.

The email generating script

Most of the work is done by the svnlook program. It is called out to by the script to get the info about the change and the changed items list. I created one function to call it for both purposes, the svnlook function. It invokes the svnlook process using the child_process module and captures all of the output in a string. It sends that string to a callback function for processing if svnlook exits successfully (exit code is 0).

This routine calls svnlook and then sends information from it to a callback

This routine calls svnlook and then sends information from it to a callback

Other than that, there is a minor bit of logic related to processing the information retrieved from svnlook and then a very simple plain text message is built. That final message is sent using the excellent Nodemailer module.

To allow this script to easily send emails to different users of different repositories, I created a separate recipients.js file that is simple to configure. It contains an object for listing users, an object for listing repositories, and then arrays in those repository objects for assigning recipients.

var users = {
    example: "'Example User' <example@brentscode.com>",
    another: "'Another User' <another@brentscode.com>"
};

var repos = {
    reponame: {
        recipients: [
            users.example,
            users.another
        ]
    }
    
    anotherrepo: {
        recipients: [
            users.example
        ]
    }
};

module.exports = function(repo) {
    return repos[repo].recipients.join(", ");
}

You will need to make some modifications in each script to properly configure things. The DOS batch file will need to point at where you place the .coffee and .js scripts. Those script files will need the CONFIG variable, repository info, and email addresses to be checked and configured as necessary. This should only take you a matter of minutes. If this works, you will likely see a little extra delay when committing changes as the SVN process invokes this code and waits for it to finish.

Links

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s