Deploy GitHub Repositories with GoHub

One popular way to deploy a web application, or even a set of static HTML files in the case of Jekyll blogs, is to add a bare repository on your server with a post-receive hook that catches the files when they’re pushed and copies them into the right place. But that’s a little inconvenient. To deploy you have to grab your computer, pull down the latest changes and then push to your second remote. What if you want to do it from your phone, reviewing pull requests and merging them on the go? What if you want to edit your Jekyll blog’s repository on Prose and have the changes immediately take effect?

That’s the problem GoHub attempts to solve. It’s a tiny webserver (written in the Go language) that listens on a port for messages from GitHub’s WebHook API. Any time a commit is pushed to GitHub, they send a JSON notification to your GoHub listener, and it runs the shell script of your choice when the specified branch (usually “master”) changes.

The original GoHub script was created by adevan, but I made my own fork that includes some extra goodies. It includes a magical setup script that sets everything up for you, as well as an Upstart script. (Configurations and logs are also under /etc/gohub in the fork.) So if your Linux distro is still using SystemV instead of Upstart, you probably want to use the original instead of the fork. (At least until I get around to writing a SystemV script and amending the setup…) If you’re on Ubuntu, you’re good.

Assuming you already have Go installed, it’s a simple matter of cloning the repository and running the setup script.

git clone https://github.com/redwallhp/gohub.git
cd gohub
chmod +x ./setup
sudo ./setup

Then you need to add your watched repositories to /etc/gohub/config.json. Each object should specify the repository name (in the form of gohub not redwallhp/gohub), the branch (master in most cases) and the path to the shell script that should be run. The best place to keep them is in /etc/gohub/scripts, to keep everything together and save your sanity in the future.

What should one of those scripts look like? Here’s a super simple example that just takes the files checked out and copies them to the public directory the web server is looking in. This works well for PHP projects.

#!/bin/bash -l

GIT_REPO=https://github.com/me/awesomeapp.git
TMP_GIT_CLONE=~/tmp/git/awesomeapp
PUBLIC_WWW=/var/www/sites/awesomeapp

git clone $GIT_REPO $TMP_GIT_CLONE
cp $TMP_GIT_CLONE $PUBLIC_WWW
rm -rf $TMP_GIT_CLONE
exit

The README file has the script I use to build and deploy Jekyll sites.

Once you have everything set up to your liking, start the server by running service gohub start. This invokes the Upstart script and starts the server daemon.

Now all that’s left to do is add the WebHook on GitHub. Go into the settings for the repository, select Service Hooks, and then WebHook URLS. Paste in the appropriate URL, which follows this convention:

http://example.org:8392/reponame_branch

So if your repository URL is https://github.com/me/awesomeapp.git, and your domain is example.org, your WebHook URL would be http://example.org:8392/awesomeapp_master.

Save the settings on GitHub, and test out your new Git deployment system. If you make a change and push the commit, the changes should take effect momentarily.