Jekyll Plugin Issue with GitHub Pages

For this blog, I knew I wanted to be able to customize it and did not want to learn how to customize WordPress themes. The idea of using a static site generator like Jekyll was appealing to me because I would not have to deal with a database. Also since GitHub Pages hosts and automatically builds Jekyll sites, I would not have to deal with hosting. I went about installing Jekyll locally, created a starter blog site and pushed my changes to GitHub. tongueroo.com was up and running quickly!

Then I wanted to embed a YouTube link to a blog post. @joelverhagen posted a simple Jekyll YouTube Embed Plugin gist. I tested locally and it generated the blog post and site fine. But when GitHub Pages tried to build the static html files it failed with an Liquid Exception: Unknown tag 'youtube' error message.

Apparently and understandably, GitHub Pages does not allow any arbitrary plugin as part of their Jekyll build process; specifically, bundle exec jekyll build —safe is ran. Instead GitHub Pages whitelists a limited set of Jekyll plugins listed here, only 4 at the time of this writing. So if you want to use a plugin that is not yet officially supported, you will have to ask GitHub support to add it. Here is an example: "Please please , whitelist jekyll-asciidoc plugin". Jekyll's Plugin documentation page suggests this workaround:

You can still use GitHub Pages to publish your site, but you’ll need to convert the site locally and push the generated static files to your GitHub repository instead of the Jekyll source files.

The workaround is not as seamlessly as just simply pushing your branch to GitHub and having GitHub Pages automatically build the static site. I could had followed the suggestion and written a rake task to automate this locally but then I would have to remember to run the one extra command.

Taking Over Continuous Integration with CircleCI

Jekyll documentation has a neat example of Continuous Integration with html-proofer. Running html-proofer will ensure that the html output will not have any broken links, images, etc. So I figured that I'd kill two birds with one stone and set up continuous integration on CirleCI. It will both run html-proofer and build the static html files. The workflow:

  1. Push to a special gh-pages-ci branch
  2. CircleCI watches only the gh-pages-ci branch
  3. Test site via html-proofer
  4. Build the static html files
  5. Push the static html files to the git master branch
  6. This triggers GitHub Pages to update the site

I chose to use the gh-pages-ci branch because I'll likely use this technique for static html projects sites where GitHub Pages watches the gh-pages instead of master branch. The relevant scripts used in this workflow are below:

The rake task in the Rakefile that runs html-proofer:

require 'html/proofer'

task :test do
  sh "bundle exec jekyll build"
  HTML::Proofer.new(
    "./_site",
    check_html: true,
    only_4xx: true
  ).run
end

The script/build_html script that will build the Jekyll site and push it to the master git branch:

#!/bin/bash -ex

# Setup git so we can use it
git config --global user.email "you@email.com"
git config --global user.name "CircleCI build_html script"
# remove changes from current gh-pages-ci branch
git checkout -f
git checkout master

# Make sure that local master matches with remote master
# CircleCI merges made changes to master so need to reset it
git fetch origin master
git reset --hard origin/master

# Gets _site/* files and pushes them to master branch
# Note: CircleCI creates vendor and .bundle files
mv _site /tmp/
rm -rf * .bundle .sass-cache
mv /tmp/_site/* .
git add -A .
git commit -m "CircleCI build_html: copy _site files that was generated from gh-pages-ci branch"
git push origin master

The circle.yml that is configured to only watch for changes in the gh-pages-ci branch:

general:
  branches:
    only:
      - gh-pages-ci
    ignore:
      - master
test:
  override:
    - bundle exec rake
deployment:
  build_html:
    branch: ["gh-pages-ci"]
    commands:
      - ./script/build_html

One CircleCI Gotcha

CircleCI is great about being security conscientious. They set things up so that a deploy read-only ssh key is used to clone the repo. Since the build_html script above pushes to master at the end, you will need to add a key that has write access to the repo. This is a simple 1-click step in "Project Settings -> Permissions / Checkout SSH Keys".

CircleCI Checkout SSH Keys

Summary of the Final Flow

All I have to do now to update the blog is make modifications to the gh-pages-ci branch and then run git push. It was more work to set this all up than just having GitHub Pages build the Jekyll site but the site will always be checked by html-proofer now. And now I am also able to use any Jekyll plugin that I need :thumbsup: