HOWTO: Instant trigger Jenkins for a new build with a SVN post-commit (DS1511+)

Required Software and OS Installed:
– DSM version: 3.1
– wget
– Jenkins
– svn 

In my previous articles I described how to install SVN and how to install Jenkins on a Synology NAS DS1511+ ( or any other linux box ). This post will continue the setup of a development environment and will demonstrate how to create a post-commit SVN hook to trigger a build with Jenkins. 

Your project should be already setup in Jenkins. Pressing the “Build Now” button should checkout the sources from your Repository and build & test your sources. The next step is to automate the process that every commit in your repository should ignite a new incremental build in Jenkins. We now no longer need to poll the SCM anymore and Jenkins will only set to action if there is something to do.

A way to archive this, is using a feature from SVN called hooks. Subversion’s hook scripts provide a powerful and flexible way to associate actions with repository events. The only event that is interesting for Jenkins is the commit event which often mean that new code has been added or existing code has ben altered and It’s time to test the new build.

Installing the Script

The post-commit script can be downloaded here save it as post-commit inside your PATH_TO_REPOSITORY/hooks directory. Make it executable for the svnserve. 

 

DON’T COPY & PAST!
This below is for demonstration purposes only 
#!/bin/sh

#
# Jenkins SVN Build trigger script by Wessel de Roode Aug’ 2011
#

# Please adjust
SERVER=localhost                                                
PORT=8080       
WGET=/opt/bin/wget
SVNLOOK=/opt/bin/svnlook

# Don’t change below this point
###############################

REPOS=”$1″
REV=”$2″
UUID=`/opt/bin/svnlook uuid $REPOS`

echo “——————————————————-“>>${REPOS}/wget.log
#
# Check if “[X] Prevent Cross Site Request Forgery exploits” is activated
# so we can present a valid crum or a proper header
BREAD_URL=
http://’${SERVER}:${PORT}’/crumbIssuer/api/xml?xpath=concat(//crumbRequestField,”:”,//crumb)’
CRUMP=`$WGET –append-output=${REPOS}/wget.log –output-document – ${BREAD_URL}`
if [ “$CRUMP” == “” ]
then
HEADER=”Content-Type:text/plain;charset=UTF-8″
else
HEADER=$CRUMP
fi

$WGET
    –header ${HEADER}
    –post-data “`$SVNLOOK changed –revision $REV $REPOS`”
    –append-output=${REPOS}/wget.log  
    –output-document “-“
    –timeout=2
    http://${SERVER}:${PORT}/subversion/${UUID}/notifyCommit?rev=$REV 

# Debug line
echo $(date) HEADER=${HEADER} REPOS=$REPOS REV=$REV UUID=${UUID}
http://${SERVER}:${PORT}/subversion/${UUID}/notifyCommit?rev=$REV
>>${REPOS}/post-commit.log          

What does the script do?

 

  1. It is executed by the svnserve daemon when the repository has an commit event
  2. It connects to Jenkins and finds out if the install has “Cross Site Request protection” or not
  3. It than posts to a Jenkins url that triggers a new build  

Testing the script can be done in the command line with two parameters. The first is the full file path to your repository, the second is the revision number to check out. an example is below where the path to the repository is /opt/svn/test and the revision number of 128:

./post-commit  /opt/svn/test 128

Now check Jenkins if it is building a new build of your project, and check the log files in your repository directory called:

wget.log containing the wget output which gives feedback about the two transactions
post-compile.log Contains the retrieved url and other variables used during the process

A successful triggered event should initiate a build in Jenkins and an shows output on the wget.log as follow:

 

Syno> cat wget.log 
——————————————————-
–2011-08-27 20:20:54–  http://localhost:8080/crumbIssuer/api/xml?xpath=concat(//crumbRequestField,%22:%22,//crumb)
Resolving localhost… 127.0.0.1
Connecting to localhost|127.0.0.1|:8080… connected.
HTTP request sent, awaiting response… 200 OK
Length: 39 [text/plain]
Saving to: `STDOUT’

Resolving localhost… 127.0.0.1
Connecting to localhost|127.0.0.1|:8080… connected.
HTTP request sent, awaiting response… 200 OK
Length: unspecified [text/html]
Saving to: `STDOUT’
NOTE

 

If the “[ ] Cross Site Request protectionis switched off, the first query will result in an 404 error as shown below:

 Syno> cat wget.log 
——————————————————-
–2011-08-27 21:12:08– http://localhost:8080/crumbIssuer/api/xml?xpath=concat(//crumbRequestField,%22:%22,//crumb)
Resolving localhost… 127.0.0.1
Connecting to localhost|127.0.0.1|:8080… connected.
HTTP request sent, awaiting response… 404 Not Found
2011-08-27 21:12:08 ERROR 404: Not Found.

–2011-08-27 21:12:08– http://localhost:8080/subversion/168-96b-4949/notifyCommit?rev=61 
Resolving localhost… 127.0.0.1 
Connecting to localhost|127.0.0.1|:8080… connected. 
HTTP request sent, awaiting response… 200 OK 
Length: unspecified [text/html] Saving to: `STDOUT’

This 404 Not Found Error is not a problem just part of the detection phase.

Happy Coding!

 

Useful links:

https://wiki.jenkins-ci.org/display/JENKINS/Subversion+Plugin

post-commit download

Leave a comment