Thumbnail image

Static site building and CI/CD - Hugo & Travis CI

Wed, Mar 25, 2020 4-minute read

After setting the goals of how I wanted to deploy this site in my blog.init post, this site has come together using exactly the tools I said I was wanting to use.

How This Site Functions

The website itself is hosted on GitHub Pages. There are a total of three repositories that this project uses. The first holds the files used by Travis CI to build the public directory. The second is what is hosting the GitHub Pages site. Travis CI pushes the public directory which contains the website files to the second repository to host them. The third is the forked theme repository with changes that I wanted to make to a theme that I liked.

Hugo - Static Site

The static site was built using Hugo. It was relatively easy to get up and running and figure out how everything works. The theme that I chose was hello-friend-ng by Djordje Atlialp. There were a few stylistic things that I didn’t like. I forked the theme repository and made my changes. After that, my fork was installed as a submodule. Most of the work for Hugo was done in config.toml, structuring the site layout and writing the posts. A builder GitHub account used by Travis CI to pushes the website files to the GitHub Pages repo.

Travis CI - Builder - CI/CD

The hardest part of this was getting Travis CI working exactly how I wanted it to. Having never worked with it in the past, there were some hiccups. I had issues with getting .travis.yml to trigger builds. After pushing to the repo, Travis CI wasn’t building new pushes to the master branch. There were no errors in Travis CI, the builds just wouldn’t start.

Initially, I thought it was an issue with whitespaces leading to an invalid config for Travis CI. I went through the process of essentially recreating the file from scratch to ensure there were no hidden whitespaces. The builds were still not triggering.

After that, I played around with different configurations for builds and refactored some things. This also resulted in no builds starting. Eventually, I removed the repos, unlinked Travis CI from GitHub and readded everything. This did fix the build issues.

The builds still needed some work. The builds were failing due to being unable to pull the submodules from GitHub. I realized that I had setup to clone via SSH rather than HTTPS. After fixing that, the builds were successful and everything was displaying correctly via browser.

This is what the final .travis.yml looks like:

language: go
  - master
  - go get
  - hugo
  local_dir: public
  repo: al-haras/
  target_branch: master
  provider: pages
  skip_cleanup: true
  github_token: $GITHUB_TOKEN
  email: $GITHUB_EMAIL
    branch: master

Travis CI makes it easy to deploy with GitHub Pages as it’s one of their supported deployment methods. What Travis CI does is installing the latest versions of Go and Hugo. It then uses Hugo to build the files provided in the repo. The resulting public directory is pushed to the al-haras/ repo.

Lessons Learned & General Thoughts

One of the benefits of Hugo is that it is very fast to build the site after changes are made. With Travis CI, the environment is installing Go and Hugo before building the site. This makes the build times much longer than if I were to make a change on my local machine. I think it would be great for serving a basic website installed on something like an EC2 instance. I do want to see if there is a way to refactor this to run quicker with Travis CI. Travis CI builds are taking a few minutes, while locally builds are done in a fraction of a second. Hugo itself is very easy to use and has good documentation.

Travis CI seems pretty decent when it is up and running but I didnt like that builds were not starting and the fix was me unlinking and relinking the GitHub account. Other than that it was very simple to use. Once it was working, I quite liked it for this project. I am curious how the paid version is compared to the free version and what additional features are offered. Something that I like is that I did not need to install and maintain it on a server like I’ve done with Jenkins.