Gitolite to Jenkins Post Commit Kick
Jenkins is a great tool for assuring the quality of software, however kicking off Jenkins jobs is time intensive and promotes monitoring the jobs manually. Gitolite is a great tool for managing Git source repositories. Jenkins supports Git polling, however in my experience of using Jenkins (and it’s ancestor Hudson) the polling algorithm doesn’t scale well. I’ve found pushed based notifications from the source repository systems into Jenkins provide the feedback cycle I desired.
Git has quite a few hooks, which range in relevance to a remote repository. You may be tempted to look at post-commit, however this hook is only useful on local systems. The most interesting for building a post commit hook is the post-receive. When you perform a `git push`, a number of interesting subcommands are run to accomplish moving the commits to remote remote. On such command is `git-send-pack` on the client side. This invokes `git-receive-pack` on the server side, which will invoke the hook `post-receive`.
Awesome, however Gitolite utilizes a number of hooks, which you can find symbolic links to the magical land of the Gitolite binaries themselves. Gitolite provides us with a service-wide `post-receive` hook though. Sweet, no more per-repository management.
So we place our hook at `~/.gitolite/hooks/common/post-receive`, then run `gitolite setup`. This should work well. On to the contents of the script!
How will Jenkins know we have updated a repository? The Git plugin exposes an input at $JENKINS_URL/git/notifyCommit using the HTTP Get method. The input takes a Git URL as the query parameter ‘url’, which will be matched against the project’s Git URL. The input mechanism requires to have the Poll SCM checked, however you do not need to enter any values.
Easy enough to hit an HTTP service via a script using either `wget` or `curl`. We have one unit of information missing now, the repository URL. In my setup the base is well know, as `git@git:`, however the repository name still needs to be filled in. As our hook is Gitolite wide, hardwiring any specific repository is a bad idea. Lucky for us, GItolite sets a number of environment variables. One such variable is GL_REPO, which contains the name of the repository.
Tying the Rod and Hook
I use a script similar to the following, placed at ~/.gitolite/hooks/common/post-receive.
#!/bin/sh JENKINS_URL=http://ci.dev GIT_URL=git@git echo -n "Notifying Jenkins..." wget -q $JENKINS_URL/git/notifyCommit\?url=$GIT_URL:$GL_REPO -O /dev/null echo "done."
To install the script, you must execute `gitolite setup`.