I automated the deployment of this website with Travis CI, Github, Hugo and Github Pages. The website gets build from each push to master and, if the build is successful, deployed to Github Pages for website hosting.

Introduction

A few months ago I wrote an article describing how interesting it can be to automate the deploy workflows - Automate Simple Deploy Workflows - Cool!. The easeness of deploying automatically was appealing but it still required some manual work. This is due to the way I wrote the deploy scripts.

During the last few days I’ve been thinking about better ways to automatically deploy this website, from a repository where its source code is hosted to another repository that serves as a Github Pages’ repository.

The initial article I wrote had one lazy script - deploy-sh - that did all the hard work of compiling the website and pushing it to the remote host. That wasn’t good enough for me.

When I started thinking about this, I set some goals:

To only manage one repository. One is enough.

To not have to insert any credentials when pushing to remote but still use them.

The build and deployment had to be done for each commit to master. This is the only way for the website to be updated.

It had to be triggered without me doing anything other than pushing the source code to the original repository.

This was bad for several reasons. The website was built along with deploying it. It needed acess to an environment that was already configured git. It didn’t provide any information of what commit was deployed.

I decided to revamp this script, from scratch. First I decided to use an environment variable called GITHUB_API_KEY to represent a personal token that can be used to push the changes.

This presented a challenge: CNAME was replaced in each build. To circunvent this, I added the CNAME file to the content of the website. Now, CNAME is copied along.

I wanted to know what commit I was deploying from so I added a simple line to this script: HASH=$(git rev-parse --short HEAD). This gives me the commit hash of the latest commit in HEAD - this represents the last commit to master since Travis CI is configured to only build on master commits.

It tells me what commit was used for deployment, along with an URL to that commit.

After that is done, the script cleans up the assets from the Travis CI environment and exits. The script got 10 lines longer but it became much more effective. You can see the whole script here.

Configuring Github

After the script was done, I had to configure a personal access token. This can be done on the Settings of your Github profile. Under “Developer settings”, there’s a section called “Personal access tokens”.

A personal access token will allow you to authenticate with Github without having to share your credentials. It also allows you to set the exact permissions of your access token.

In this case I only wanted to push to my public repo. That’s exactly the only permission I gave to it: repo.public_repo.

Configuring Travis CI

With Travis CI, I just wanted to have it export 3 shell environment variables. The ones I talked initially. So I configured:

GITHUB_API_KEY

GITHUB_EMAIL

GITHUB_NAME

These environment variables which are configured to be hidden from the logs, allow me to push to another repository without disclosing my credentials on Github itself.

Conclusion

With this solution I reached my initial goals. I now have fully automated deployments from each commit to master.

Now that the basics of the deployments are done, adding testing or minimazing assets automatically should be fairly simple to do.