Github’s web hooks make it surprisingly easy to write commit triggers.
I’ve been using Github for awhile now and I’ve found it to be a very handy little service. I recently discovered just how easy it is to add commit triggers to it, however.
If you look under Settings for a repository and select the Service Hooks option, you’ll see a whole slew of pre-written hooks for integrating your repository into a variety of third party services. These range from bug trackers to automatically posting messages to IRC chat rooms. If you happen to be using one of these services, things are pretty easy.
If you want to integrate with your own service, however, things are almost as
easy. In this post, I’ll demonstrate how easy by presenting a simple
WSGI application which can keep one or more local repositories on a
server synchronised by triggering a git pull
command whenever a commit is
made to the origin.
Firstly, here’s the script:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
|
Aside from the Python standard library it also uses the GitPython library for accessing the Git repositories. Please also note that this application is a bare-bones example — it lacks important features such as logging and more graceful error-handling, and it could do with being rather more configurable, but hopefully it’s a reasonable starting point.
To use this application, update the REPO_MAP
dictionary to contain all the
repositories you wish to watch for updates. The key to the dictionary should be
the name of the repository as specified on Github, the value should be the
full, absolute path to a checkout of that repository where the Github
repository is added as the origin
remote (i.e. as if created with git
clone
). The repository should remaind checked out on the master
branch.
Once you have this application up and running you’ll need to note its URL. You then need to go to the Github Service Hooks section and click on the WebHook URLs option at the top of the list. In the text box that appears on the right enter the URL of your WSGI application and hit Update settings.
Now whenever you perform a commit to the master
branch of your Github
repository, the web hook will trigger a git pull
to keep the local repository
up to date.
Primarily I’m hoping this serves as an example for other, more useful web
hooks, but potentially something like this could serve as a way to keep a
production website up to date. For example, if refs/heads/master
in the
script above is changed to refs/heads/staging
and you kept the local
repository always checked out on that branch, you could use it as a way to push
updates to a staging server just by performing an appropriate commit on to that
branch in the master repository.
Also note that the webhook interface contains a lot of rich detail which could be used to do things like update external bug trackers, update auto-generated documentation or a ton of other handy ideas. Github have a decent enough reference for the content of the POSTs your hook will receive and my sample above only scratches the surface.