Using External Jekyll Themes and Gems on Github Pages with Travis CI

I recently decided to start blogging (for real, this time). As someone from the developer community, I know that Github Pages is the one-true way to host your website.

Github Pages provides free hosting, git based deployment, support for custom domains and a lot of other nifty features. It uses Jekyll, a static site generator which underwent a massive overhaul recently and now includes gem based theming and plugins support. Previously, you had to include all the assets of the theme and there were only few plugins supported by default at the time.

I was excited when I found out the perfect theme for my blog, but turns out Github Pages only supports a select few themes and plugins. I could still build the site on my machine and push it to Github, but that would defeat the purpose of using Jekyll in the first place.

I Googled (more like Duck Duck Go’d) around figured out that using a continuous integration system like Travis CI (which is free for Open Source) was the proper way to do it. I also found a nice example on how to proceed forward. I’ve outline what I did below.

Create a new branch

Github Pages builds from the master branch for User or Organization Pages sites or the gh-pages branch for Project Pages sites. I created a new jekyll branch on my personal repository for the source. It also makes things easier if you change the default branch in the repository settings. Repository default branch

Get a Github API token

You will be using Travis CI to commit to the default or gh-pages branch. Using passwords is insecure to use for third party deployment, so Github provides Personal Access Tokens to authenticate. Create a token using this link and select the public_repo scope (or the repo scope if you are using a private repository). Make sure you keep the token safely or someone else might use it to authenticate as you on Github.

Configure Travis

Go to https://travis-ci.org/profile and enable your repository by toggling the switch. Add your Personal Access Token as an environment variable. The token is stored encrypted on their servers and only decrypted during builds. You can choose any name for the environment variable which you will be using later (I used GH_TOKEN). I also selected the “Build only if .travis.yml is present” and “Build pushes” options to simply things. The former options prevents the deployed repository from being built (Jekyll does not copy that file to the _site directory) while the later runs the build process as soon as you push to Github.

Travis repository settings

Travis is configured using a .travis.yml file on the repository. You can see my configuration here.

language: ruby
rvm:
  - 2.4.0
script: bundle exec jekyll build
branches:
  only:
    - jekyll
sudo: false
after_success:
  - cd _site
  - git init
  - git config user.name "Shritesh Bhattarai"
  - git config user.email "shritesh@shritesh.com"
  - git remote add upstream "https://$GH_TOKEN@github.com/shritesh/shritesh.github.io.git"
  - git fetch upstream
  - git reset upstream/master
  - git add -A .
  - git commit -m "[Build] ${TRAVIS_COMMIT}"
  - git push -q upstream HEAD:master

The configuration is easy to understand. I set the language as Ruby and used the version 2.4.0 for Jekyll. Travis will then execute the script bundle exec jekyll build which compiles the site to _site directory. I have also configured it to build only on the jekyll branch of the repository.

After it is successfully built, it changes into the _site directory, initializes an empty git repository, sets the git credentials to be me and adds an upstream repository using the token stored previously for authentication. It fetches the repository and stages the changes. The TRAVIS_COMMIT environment variable denotes the latest commit hash, which is used in the commit message. Then, it pushes it to the master branch on Github.

You could also test your site using html-proofer gem as outlined in Jekyll’s documentation on continuous integration.

Similarly, you can also use Travis to deploy to another service, which I intend to do soon as Github Pages does not yet support HTTPS on custom domains.

Push your Jekyll Site

Now push your site to Github and Travis should build and deploy your site.

Travis build status

Congratulations, you can now use any theme or gem on Github Pages.

Update: I have moved the site to a new domain and Netlify. They provide Let’s Encrypt certificates on all their domains domains and also handle the continuous deployment that Travis did here.


Thank you for reading my first blog post. You can follow @shritesh on Twitter.