Auto-deploying GitHub pages via GNU Make¶
The GitHub pages system allows you to associate a set of static (or templated) HTML with a repository or user. It is a very useful service but is accessed in an interesting way. If your repository contains a gh-pages branch, it will appear at the URL http://user.github.com/repository. All of these notes are maintained in a GitHub repository written in \(reStructured Text\) format.
The notes themselves are a part of a relatively standard Sphinx project. The project itself was generated via the \(sphinx-quickstart\) command. The interesting bit is in the Makefile. The Makefile itself is very similar to that generated by sphinx-quickstart. To support deploying to the gh-pages branch, we first of all need to know which branch we’re on and, so that we can generate a commit message, when we’re running the build.
1 2 3 4 5 6 | CURRENT_BRANCH = $(shell git name-rev --name-only HEAD)
ifndef CURRENT_BRANCH
CURRENT_BRANCH = $(error Could not get current branch.)
endif
DATE=$(shell date)
|
Lines 1 to 4 use some git plumbing commands to get the current branch name. If the branch name could not be obtained for some reason, the CURRENT_BRANCH variable is set to a magic value which will trigger an error when evaluated. We do this so that the error will only be generated if we try to use the CURRENT_BRANCH variable.
Line 6 simply gets the current date for the auto-commit message.
The meat of the deployment is done via the deploy target:
deploy: clean dirhtml
git checkout gh-pages
-rsync -a --delete --exclude=.* --exclude=.git --exclude=$(BUILDDIR)/* $(BUILDDIR)/dirhtml/ .
-git add .
-git add -u
-git commit -m 'Automatic build commit on $(DATE).'
git checkout ${CURRENT_BRANCH}
This target first makes sure we’ve cleaned and built the current ‘latest’ version. The remainder is quite straightforward: we switch to the gh-pages branch. Since checking out a new branch will keep the untracked files in the working directory, the $(BUILDDIR) is still in place. We use rsync to update the root directory from the build directory. Note that we explicitly exclude dot-files to make sure that rsync doesn’t delete anything of importance.
The build directory itself will be ignored by git since there is a .gitignore file in the gh-pages branch which explicitly ignores it. We then use the git add and git add -u commands to add any new or modified files and to remove any deleted files. Finally we generate an automated commit and return to the original branch.
Note
We prepend a dash (-) to all commands between the checkout of gh-pages and $(CURRENT_BRANCH) so that if the commands fail for some reason, we don’t end with the wrong branch checked out. The dash causes Make to ignore failures in a particular command and to keep going.
Initially this target also explicitly stashed and un-stashed any uncommitted changes but I removed that after deciding that deployment is something that \(should\) only be done to a tree with no uncommitted changes.