Andy Van Slaars

Andy Van Slaars

moon indicating dark mode
sun indicating light mode

Continuous Deployment of Hugo with GitHub, Codeship and

June 23, 2016

I like writing code and building applications, but I’d like to focus those efforts on new and interesting projects, not on building and maintaining yet another blogging engine. So, when I started this blog, I decided to go with a static site generator. I am using Hugo, and after about six months, I am very happy with that decision.

One of the things I knew when I started this blog, was that if publishing were to become too cumbersome or time consuming, I would be even less likely to write on a regular basis - publishing regularly is hard enough for me without my tools getting in the way. Keeping that in mind, I decided that I needed to setup a low-friction process for publishing content right from the beginning.

I’m a huge fan of git and GitHub, so a continuous deployment setup that leveraged my git repository was a no-brainer.

My current setup relies on GitHub, Codeship, Hugo and Surge to deploy a static site anytime changes are committed to a specific branch of my repo. In this post, I’m going to show you how this is all configured so you can have a similar setup if you’d like.

Assumptions and Prerequisites

This post assumes that you either have a Hugo site setup, or that you are going to follow the instructions on the Hugo website and get one set up.

It also assumes that you have a Github account, have added your Hugo project to a repository on github and that you have configured Surge and have a Codeship account and have created a project that relies on your GitHubrepo. Each website has clear instructions for setup, so rather than try to explain the initial setup, I’ll let you rely on the official documentation for each service. Once all of this is ready to go, come back here to see how to connect it all.

I am using a custom domain on Surge. This isn’t required, but if you don’t specify a domain, you’ll be assigned something at random. This will require you to use the CLI to list your projects to figure out where this is hosted and it’ll make it tough for people to find your site, so I highly recommend it. Here are some instructions for adding a custom domain to your project on surge.

Getting a Surge Token

If you’re using Surge for the first time, the quickest way to make sure it is fully configured is to build your Hugo project locally and publish via the Surge CLI once. On the first run, you’ll be prompted to setup your account right in the terminal.

Now that you have a surge account, you’ll need to generate a token for use on CodeShip. In the terminal, run:

surge token
# token: <TOKEN VALUE>

You’ll be using that token value in the next step.

Codeship Environment Variables

In your Codeship project, navigate to the environment variables under Project Settings > Environment Variables

Codeship Environment Variables Navigation

On the environment variables entry screen, create two entries:

SURGE_LOGIN - This will be your account email

SURGE_TOKEN - This is the token from running surge token

Codeship Setup Settings

With the environment variables configured, now it’s time to configure the setup. We need codeship to be able to do a full build of the Hugo site from the source in the GitHub repo, so the first step is making sure we have the right version of Go installed.

Navigate to the Test link for your project, and make sure the dropdown is set to

I want to create my own custom commands

Codeship - I want to create my own custom commands

From there, you can add the following code to the setup textarea.

# Install a custom Go version,
# Add at least the following environment variables to your project configuration
# (otherwise the defaults below will be used).
# Include in your builds via
# source /dev/stdin <<< "$(curl -sSL"
# strip all components from PATH which point toa GO installation and configure the
# download location
CLEANED_PATH=$(echo $PATH | sed -r 's|/(usr/local\|tmp)/go(/([0-9]\.)+[0-9])?/bin:||g')
# configure the new GOROOT and PATH
export GOROOT="/tmp/go/${GO_VERSION}"
export PATH="${GOROOT}/bin:${CLEANED_PATH}"
# no set -e because this file is sourced and with the option set a failing command
# would cause an infrastructure error message on Codeship.
mkdir -p "${GOROOT}"
wget --continue --output-document "${CACHED_DOWNLOAD}" "${GO_VERSION}.linux-amd64.tar.gz"
tar -xaf "${CACHED_DOWNLOAD}" --strip-components=1 --directory "${GOROOT}"
# check the correct version is used
go version | grep ${GO_VERSION}

With that done, you can scroll down to the input under the “Configure Test Pipelines” heading, and either remove or comment out any commands in there since we won’t be running unit tests against this project.

Codeship Deploy Settings

With the setup instructions complete, now you’ll need to configure the deployment. Navigate to the deployment link under your project settings. Setup a deployment pipeline for the branch you want to deploy from. I have mine setup to do a new deployment any time my master branch is updated on GitHub. In the deployment pipeline, you’ll need to create a custom script entry that contains the following code:

# Install pygments for syntax highlighting
pip install Pygments
#Install surge
npm install -g surge
# Install and compile Hugo
go get -u -v
# Get to files that have been copied from repo
cd ~/clone/
rm -rf ./public
# Build site
# Deploy to surge
surge --project ./public/ --domain <YOUR DOMAIN>

Make sure you replace <YOUR DOMAIN> with your domain name, whether it’s a custom domain or the one Surge generated for you on your initial manual deployment.

These commands will:

  1. install Pygments for syntax highlighting
  2. install Hugo to generate the site from your source
  3. delete the ./public directory in your repo if it’s there (mine is ignored via .gitignore)
  4. Build your site with the hugo CLI (which will create and populate ./public with your updated site)
  5. run the surge CLI to deploy whatever is in ./public to your domain

Note: If you don’t need code highlighting, you can do away with the pip install Pygments line.


Now if you have everything properly configured, you should be able to add something to your local Hugo project, commit your changes via git and push to the branch you’ve configured the deployment pipeline for (master in my case) and once Codeship has done its thing, your site should be updated.

Thanks to a handful of awesome, free tool and services, with a little bit of up-front setup, you can have updates to your site automatically deployed and you can focus on what matters, your content!