· Git how to Hugo web

Automating Your Hugo Website with Git

As I wrote in my first post here, I wanted to use version control for this website. Version control is a software development management tool that gives separate layers–in this case, I can be working on a new feature or design and not have it appear on the website until I’m ready. It also lets me undo things and change course easily.

I chose to use Git mainly because it’s pretty standard but also to give me a chance to learn it in a real-world environment.

Years from now, I don’t want to have to know what version of Hugo to use to regenerate an old website if needed. So I actually have two Git repositories for this site:

Writing Workflow

Writing for the website is pretty simple.

  1. I’ve cloned the source repo onto my daily-use Mac. When I’m ready to write something new, I run hugo new blog/title.md then edit the file that’s created.
  2. When I’m ready to test, I’ll run hugo server -Dw. Hugo will watch the files and rebuild the test site if there are changes. I can check to see how the new post will appear using a web browser.
  3. Once I’m happy with it, I commit the changes: git add, git commit, and git push.

But remember, this is only the source used by Hugo to make the website. (Since I want to separate the two repositories, I added the public/ directory Hugo uses to store the test files to the .gitignore list.)

How to Automatically Deploy

The key part in making the updated website visible on the Internet is the last part of step three: git push. On the server, I run a Git hook located under hooks/post-receive:

#!/bin/bash
GIT_REPO=$HOME/website-source.git
TMP_GIT_CLONE=$HOME/tmp/website-source
PUBLIC_WWW=/srv/www

# Wait up to 2 seconds for the STDIN to get here.
read -t 2 from_commit to_commit branch_name

# Only deploy if the master branch was pushed. Full variable is similar to "refs/heads/master".
if [[ "$branch_name" != */master ]]; then
  echo "Received branch $branch_name, not deploying."
  exit 1;
fi

# Make temporary clone for site generation.
git clone $GIT_REPO $TMP_GIT_CLONE

# Run hugo using config in repo, no draft or future content will be created.
cd $TMP_GIT_CLONE
hugo

# Copy files to www server root. Some files are excluded so they don't overwrite or delete
# required files in the server root.
rsync -rvh --delete --exclude='.git/' --exclude='.gitignore' $TMP_GIT_CLONE/public/ $PUBLIC_WWW/

# We're done, so clean up.
rm -rf $TMP_GIT_CLONE

When I push the updates from my Mac, the server runs this script and I don’t have to run each command manually!

More Details

The script is based on the ones at Setting up Push-to-Deploy with git and Deploy Process. It could easily be adapted for use with other static website generators.

Some sections that might require more explanation are:

If you do something similar, make sure to run the same Hugo version on your local and server computers. That way, the site built for local testing will be the same as the one generated on the server.