This website is generated using Jekyll, a static site generator. Basically, I write the posts as Markdown files, run it through Jekyll and out pops this website,

For as long as I have been building the site in this way I’ve built the site locally and commited the contents in to my Github Pages Project. This step has always been a bit tedious, ensuring that I build the site to the correct folder with the .git references setup and up to date isn’t difficult, just a pain.

At work we use Travis extensively for our build pipeline, I already have a Travis account personally so it occurred to me that I should be generating the site directly off commits to the blog base project, where I write my Markdown.

What I will need

The Travis Account

A travis account is required to be able to do the builds, for more information see the Travis website.


The github token allows processes to access your github account and perform the actions that the token has been permissioned to perform. To create a new GITHUB_TOKEN you can navigate to the Generate New Token page in you logged in Github account.

For this, I created a token that had access to commit to repos. Its sensible to have specific tokens for specific tasks in my opinion - rather than one super token that you use everywhere.

The Travis Gem

We are going to be encrypting the GITHUB_TOKEN into the .travis.yml file, so we need the travis gem to perform this. To install run

gem install travis

If you’ve got Jekyll, I’m assuming you’ve already got the Ruby infrastructure on your machine.

The Build Scripts

Below is the build script I use; I’ll break down the sections.

#! /bin/bash

set -e

MESSAGE=$(git log -1 HEAD --pretty=format:%s)

function clean { 
	echo "cleaning _site folder"
	if [ -d "_site" ]; then rm -Rf _site; fi 

function clone_site { 
	echo "getting latest site"
	git clone --depth 1 $DEPLOY_REPO _site 

function build { 
	echo "building site"
	bundle exec jekyll build --lsi

function deploy {
	echo "deploying changes"

	if [ -z "$TRAVIS_PULL_REQUEST" ]; then
	    echo "except don't publish site for pull requests"
	    exit 0

	if [ "$TRAVIS_BRANCH" != "master" ]; then
	    echo "except we should only publish the master branch. stopping here"
	    exit 0

	cd _site
	git config "Travis Build"
    git config
	git add -A
	git commit -m "Travis Build: ${TRAVIS_BUILD_NUMBER}. ${MESSAGE}"
	git push $DEPLOY_REPO master:master


The clean function ensures that the location the static site is generated into is gone (in the default cause this is the _site folder)


When we do the build in travis, we need to have the destination github pages project cloned into _site for writing. THis function does that clone to get the latest.


The build function runs jekyll build which by default will generate the site into _site folder


The deploy function is the main section for commiting the updates in the github pages project. This function ensures that the Travis run isn’t a PR and that the branch is master if these conditions are satisfied it will commit the changes to _site and push to make them available.

The Makefile

To simplify the running of the commands - and to allow them to be used locally easily, there is a Makefile

.PHONY: initpost clean clone_site build deploy

	@bash -c "./scripts/"

	@bash -c ". scripts/ && clean"

	@bash -c ". scripts/ && clone_site"

build: clean clone_site
	@bash -c ". scripts/ && build"

deploy: build
	@bash -c ". scripts/ && deploy"

Running deploy target will automatically run the build target, which in turn runs the clean and the clone_site. Now to build the site we can simply run

make build

The .travis.yml file

To pull this all together and trigger the build when we commit, we need the .travis.yml file.

This file sits in the root of the project and when committed, triggers a Travis build of the current branch and where applicable, the associated PR.

language: ruby
cache: bundler
    secure: dsfojisdfglksdhgflsdhgsdfghedlfs
- bundle install
- "make deploy"

This is a fairly straight forward .travis.yml file. We are telling Travis that this project is ruby based and we need to have the bundler cache available.

Before starting, we want to install all of the required dependencies from the Gemfile, in this case it is basically jekyll and the ohter jekyll plugins I use in this site.

One interesting part is the env/global/secure section. This contains my GITHUB_TOKEN in an encrypted form. To generate this, from the root of the project use the travis gem installed previously….

travis encrypt GITHUB_TOKEN=abcdefghij1234 --add

This will prompt to ask if you want to create the ENVVAR in the current folders .travis.yml file. It used the details of the repo as a seed for encryption.

Finally the job runs make deploy which will build the site and deploy it to the github pages project as a new commit.

The Travis Output

Now, when I commit changes to my blog base project, it runs in Travis and I get output similar to this;

Installing SSH key from: default repository key
Using /home/travis/.netrc to clone repository.
$ git clone --depth=50 --branch=master owenrumney/blogbase

Setting environment variables from .travis.yml
$ export GITHUB_TOKEN=[secure]
$ rvm use default
$ export BUNDLE_GEMFILE=$PWD/Gemfile
Setting up build cache
adding /home/travis/build/owenrumney/blogbase/vendor/bundle to cache
$ ruby --version

$ bundle install
$ make deploy

cleaning _site folder
getting latest site
Cloning into '_site'...
building site
Configuration file: /home/travis/build/owenrumney/blogbase/_config.yml
            Source: /home/travis/build/owenrumney/blogbase
       Destination: /home/travis/build/owenrumney/blogbase/_site
 Incremental build: disabled. Enable with --incremental
                    done in 0.645 seconds.
 Auto-regeneration: disabled. Use --watch to enable.
deploying changes
[master a1e2f08] Travis Build: 6. Update the build script to use the Makefile
 1 file changed, 2 insertions(+), 2 deletions(-)
   5f492f6..a1e2f08  master -> master
The command "make deploy" exited with 0.
store build cache
Done. Your build exited with 0.
Are you confused about the ever growing number of services in AWS and Azure? Why not checkout these super useful glossaries that are always up to date!
There is one for AWS and one for Azure