Publish static Hugo site with Git hooks

2018/09/03

Storing Hugo documents in a git? The natural process of pushing a new commit; is to regenerate the site and publish it. I’m using this method on a Gitea server; it should work with similar environments.

Make sure you have access to the bare Git repository. Specifically its hooks. In Gitea, it is under the repository menu Settings -> Git hooks.

Put the following script in the post-receive hook:

#!/bin/sh -e
ARCHIVE=`mktemp`.tar.gz
HUGO=/usr/local/bin/hugo
OUT=`mktemp -d`

git archive -o $ARCHIVE master
tar zxf $ARCHIVE -C $OUT

publish() {
    # ... publishing code here ...
    # The generated static Hugo site is in the working directory
}

(cd $OUT && $HUGO) # Generate
(cd $OUT/public && publish) # Publish
rm -r $ARCHIVE $OUT # Clean up

exec git update-server-info

Update the variable HUGO to the path of the Hugo executable.

Put the publication code in the publish function. Rsync, FTP or whatever. Put those commands here.

During a git push operation, all verbose output from the scripts will be displayed. Thus, if anything goes wrong; the error message will be printed to the user.

Pushing static files to Github pages

All users on Github have access to a personal site at https://[username].github.io. For example, mine: https://carlmartus.github.io/. Follow this guide to activate.

Here’s a way of publishing to Github pages.

publish() {
    unset GIT_DIR
    unset GIT_OBJECT_DIRECTORY
    git init
    git add .
    git remote add origin "git@github.com:[USERNAME]/[USERNAME].github.io.git"
    git commit -q -m "Upload" && git push origin -f HEAD:master
}

The unset commands removes environments variables set by Git. Because the will interfere with the other Git commands.

WARNING; this method performs a FORCE PUSH that will REPLACE the entire repository history. In other words, the method treats the pages repository as a static file storage. Thus disregarding the version control aspect of the repository pushing to.

So, avoid the method if you intend to store the documents along with the generated site. At last, in order to work, the server executing the Git hook script must have its public ssh key registered on Github.