Git hook deployments

A possible approach to building and deploying static sites is outlined below. It can be a viable solution given the following conditions are true.

A workflow can be setup such that day to day development happens on the dev repo, then when ready to deploy new version of site on web server, a git push is made to the web server repo triggering a git hook that builds and updates the site.

Web repo

The webrepo will be a bare repository that when receiving a push will run a hook to build and update the website. For our purposes it will be located on the web server itself and we need SSH access to this server.

A bare repository is typically used for pulling and pushing to, it does not have a Working Tree, which is directory containing the files you edit.

Setup bare repo and build pipeline on web server

Lets setup the webrepo, we need to do this on the web server.

$ ssh me@mywebserver.com
$ mkdir webrepo
$ cd webrepo
$ git --bare init

Also create a directory for building the site.

$ mkdir build

Install pagegen on the web server.

$ pip install pagegen

We will now setup a git hook that gets triggered every time the webrepo receives a push. Git hooks are simply scripts that are run when certain events happen, in our case we will use the post-receive hook.

Create the webrepo/hooks/post-receive with the following content.

#!/bin/bash

# Ensure this is same as the build directory created above
build_dir="/home/me/build"

echo "Git checkout.."
GIT_WORK_TREE="$build_dir" git checkout -f master

echo "Building.."
cd "$build_dir"
# Ensure this path is correct and that you have an environment called production in your site.conf
"$HOME/.local/bin/pgn" --generate production

Ensure the hook is executable.

$ chmod u+x webrepo/hooks/post-receive

Lets assume the web server is setup to serve www directory. We now want to make www a symlink that points to the build/site/production directory, because that is where the our freshly built site will be found.

ln -s "$HOME/build/site/production" "$HOME/www"

To recap we have now setup the following.

├── build
│   └── site
│       └── production # Pagegen will build site here
├── webrepo
│   └── hooks
│       └── post-receive # Script run on push to trigger pagegen build
└── www -> /tmp/t/build/site/production # Symlink to site, this is what the webserver serves

Dev repo

This git repo can be anywhere, e.g. github, local or whatever. Use this repo in day to day development. If you don't have one already you can setup one on your local machine like so. We will refer to it as devrepo.

$ mkdir devrepo
$ cd devrepo
$ git init

To enable pushing changes from the devrepo to the webrepo we need to configure a git remote. A git repo may have multiple remotes. Lets assume you setup your devrepo with github, the following will list the github remote, make sure you run it from the devrepo directory.

$ git remote
origin

By convention origin is the name of the remote repository that the project was originally cloned from.

To see more detail run the command again with argument -v.

$ git remote -v

We want to add webrepo as a new remote to devrepo, we can call the remote what we want, but will just unimaginatively call it web for now.

$ git remote add web me@mywebserver.com:~/webrepo

Now we can commit, push and pull and generally use devrepo as usual, but when we are ready to update the live site we can simply commit all changes and push to webreop.

$ git push web

The push will send all changes to webrepo and trigger our hook to check out the new changes in the build directory, run pgn --generate production building the new site effectively making it available to serve through the www symlink.