With the following I will describe how the deployment of a Hugo website is automated with git hooks. If you are interested in further details to git hooks I can recommend this tutorial from Justin Ellingwood.
Automation with Git hooks
To keep track of my website I have a local git repository and a remote one on
the webserver. For deployment there is the branch public
. Whenever there is a
commit to that branch the site is rebuilt with Hugo. If the branch public
is
pushed to the webserver the content of the folder public within the git
repository is copied to the directory of the webserver. This is all done with
git hooks.
Build the Site with the pre-commit Hook
The Git hooks are located in the folder .git/hooks/
of the repository. As we want
to build the site before the commit, we use the hook .git/hooks/pre-commit
. If
it doesn't exist create it and make it executable (chmod +x pre-commit
).
#!/bin/bash
echo "*** Executing pre-commit hook"
BRANCH=$(git rev-parse --abbrev-ref HEAD)
if [ "$BRANCH" != "public" ]; then
echo "Not on branch public."
exit 0
fi
echo "Cleaning public directory.."
rm -r public/*
echo "Rebuild site.."
hugo
if [ $? -ne 0 ]; then
echo "Website build failed!"
echo "Aborting commit."
exit 1
fi
git add public/.
echo "Site built and added to commit."
exit 0
If there is a commit to the branch public
this script cleans the public
directory (as Hugo won't delete possibly removed files there) and rebuild the
site with Hugo. If the rebuild fails the commit is aborted.
Deploy the Site with the post-receive Hook
To deploy the site the hook my_repo.git/hooks/post-receive
(from the remote
repository at the webserver) is used. If it doesn't exist create it and make it
executable like above.
#!/bin/bash
#
# git post-reveive hook for (Hugo) website deployment
#
WORKDIR='/var/www/my_site'
PUBLICDIR="$WORKDIR/html"
BACKUPDIR="$WORKDIR/bak"
WEBUSER='my-user'
WEBGROUP='www-data'
while read oldrev newrev branch
do
if [[ $branch =~ .*/public ]];then
echo "Branch public updated. Deploying website.."
git --work-tree=$WORKDIR checkout -f public -- public
if [ $? -eq 0 ];then
if [ -d "$BACKUPDIR" ]; then
rm -rf "$BACKUPDIR"
fi
chown $WEBUSER:$WEBGROUP $WORKDIR/public
mv $PUBLICDIR $BACKUPDIR
mv $WORKDIR/public $PUBLICDIR
echo "Done."
else
echo "Checkout failed. Website not deployed."
exit 1
fi
fi
done
If there is a push to the public
branch of the remote repository this script
- Checks out the public folder of the Hugo site from the repository to the
working directory (
WORKDIR
). - Changes its user (
WEBUSER
) and group (WEBGROUP
) to ensure it can be read by the webserver. - Deletes the old backup (
BACKUPDIR
) if it exists. - Moves the folder with the current website (
PUBLICDIR
) to the backup location. - Moves the public directory to the website folder.
If the checkout fails the deployment is aborted.
tl;dr
With these two scripts a Hugo website can be built automatically with a git commit
and deployed with a git push
.