A Post-Receive Git Hook For Octopress

Here comes the post-receive git hook I used along with Octopress, to finish deploying the static blog server-side.

Introduction

What do we want to achieve? Well, each time a new version of the static site, built by Octopress, is pushed to the git repository, we'd like git to copy it to the document root served by Apache (/srv/www/blog-test in this example).

In order to do that, we need to write a git hook, and to fiddle a little bit with permissions.

Git hook

We're talking about a post-receive git hook. Here it is:

#!/bin/bash
#
# Git hook to finish deploying an Octopress website server-side.
#
# Each time the 'master' branch is updated, just clone it, and copy
# the content (aka the static website) to the location expected by
# the web server.
# Git must have the permission to write there.

set -e

REPO=$(basename "$(pwd)" | sed s/\.git$//)
TMPDIR=/tmp/$REPO
WWWDIR=/srv/www/$REPO

stdin=$(cat)
refs=$(echo "$stdin" | cut -d' ' -f3)

# Exit if nothing was pushed to the master branch
echo "$refs" | grep -q 'refs/heads/master' || exit 0

# Ensure the target directory is writable
[ -d "$WWWDIR" ] || echo "'$WWWDIR' doesn't exist!" && exit 1
[ -w "$WWWDIR" ] || echo "'$WWWDIR' is not writable!" && exit 1

# Clone the master branch, and copy the static website
[ -d "$TMPDIR" ] && echo "Removing '$TMPDIR'..." && rm -fr "$TMPDIR"
git clone . "$TMPDIR" --branch master && rm -fr "$TMPDIR/.git"
[ -d "$WWWDIR" ] && echo "Emptying '$WWWDIR'..." && rm -fr "$WWWDIR/*"
mv -v "$TMPDIR/*" "$WWWDIR"
rmdir "$TMPDIR"

There's a few things to notice in this script:

Settling write permissions

After that, we just have a few ownership details to solve. As you can see in the script above, git will write inside the directory /srv/www/WWWDIR. We must manually create this directory, and allow git to write there. A solution is to add git to the group www-data (which is the user Apache is running), so that they can both access it.

First, let's create the document root directory:

$ cd /srv/www
$ mkdir blog-test
$ chgrp www-data blog-test
$ chmod g+w blog-test
$ ls -l
total 4
drwxrwxr-x 2 root www-data 4096 Sep 29 19:08 blog-test

And now, just add git to the right group:

$ addgroup git www-data