Generate a Hugo website with the post-receive GIT hook


Summary

By storing Hugo website content in a git repository, a user can checkout the site from any git enabled workstation, make changes, then automatically build and deploy the site with a git push action to a remote repository. The git hook post-receive enables this automation. git hooks are a method for executing scripts when specific git actions are taken.

Details

Setup a web server and Hugo on an Internet connected server, instructions are outside the scope of this document.

On the same server create a bare git repository to hold the Hugo website. Instructions are here.

Once complete, create a $GITREPO/hooks/post-receive file with the following script.

jemurray@shell:~/git/jasonmurray.org.git/hooks$ cat post-receive

#!/bin/bash

# GIT environment variable where the 'checkout -f master' command will extract the contents of the website.  Put this directory in a location the web server can read so that the 'root /home/jemurray/jasonmurray.org-GIT/public;' can be used to serve the website without additional steps.
export GIT_WORK_TREE=/home/jemurray/jasonmurray.org-GIT

echo `pwd`
echo "Generating jasonmurray.org site with Hugo"

# Create the directory and all subdirectories if they don't exist.
mkdir -p $GIT_WORK_TREE
chmod 755 $GIT_WORK_TREE

# Check out the contents of the repository and extract the files to $GIT_WORK_TREE
git checkout -f master

# Remove any files already in the public directory, a fresh copy will be generated by hugo
rm -rf $GIT_WORK_TREE/public

# Generate the site with hugo
cd $GIT_WORK_TREE && /usr/bin/hugo                                                                                                            

# Fix any permission problems.
find $GIT_WORK_TREE/public -type f -print | xargs -d '\n' chmod 644
find $GIT_WORK_TREE/public -type d -print | xargs -d '\n' chmod 755

echo "Hugo site generation complete"

Make the script executable:

chmod 755 $GITREPO/hooks/post-receive

Committing to the remote repository automatically builds the site:

jemurray@mbp-2019:~/Documents/www-personal/current/jasonmurray.org $ git push origin master
Enumerating objects: 1043, done.
Counting objects: 100% (1043/1043), done.
Delta compression using up to 12 threads
Compressing objects: 100% (1028/1028), done.
Writing objects: 100% (1043/1043), 101.04 MiB | 1.21 MiB/s, done.
Total 1043 (delta 328), reused 0 (delta 0)
remote: Resolving deltas: 100% (328/328), done.
remote: /home/jemurray/git/jasonmurray.org.git
remote: Generating jasonmurray.org site with Hugo
remote: Already on 'master'
remote: Building sites …
remote:                    | EN
remote: +------------------+-----+
remote:   Pages            | 369
remote:   Paginator pages  |   0
remote:   Non-page files   |   0
remote:   Static files     | 117
remote:   Processed images |   0
remote:   Aliases          |   0
remote:   Sitemaps         |   1
remote:   Cleaned          |   0
remote:
remote: Total in 908 ms
remote: Hugo site generation complete
To shell.jasonmurray.org:/home/jemurray/git/jasonmurray.org.git
 * [new branch]      master -> master

Configure the web server to serve the website from the following directory: /home/jemurray/jasonmurray.org-GIT/public (partial snippet of Nginx configuration):

server {
        listen 80 default_server;
        listen [::]:80 default_server;
        listen 443 ssl default_server;
        listen [::]:443 ssl default_server;
        ssl_certificate /etc/ssl/certs/jasonmurrayorg.crt;
        ssl_certificate_key /etc/ssl/private/jasonmurrayorg.key;
        ssl_client_certificate /etc/ssl/certs/origin-pull-ca.pem;
        ssl_verify_client on;
        root /home/jemurray/jasonmurray.org-GIT/public;