Why CI a simple blog?
Just like we write automated unit tests for our applications, anything we’re pushing to the Web should be stable and we’re confident we didn’t break our site with an errant //JS
or <HTML>
tag. To do this, we’ll attach an integration service listening to our commits to the master
branch.
Choosing a Platform
Since I’m running my blog outside of Github Pages, I can’t depend on integration servies such as Travis CI and Github’s ecosystem of integrations. Have no fear, there are many Continuous Integration solutions out there for a variety of purposes. Here are a few:
- Jenkins (used to be Hudson)
While I’m familiar with Jenkins, I know from experience it requires quite a bit of RAM as well as needing a JVM. Its a great choice for running Java builds with Gradle.
- Travis CI (integrates with Github)
If we were hosting this blog on Github Pages, Travis would be a no-briner.
Since we spent a whole blog post deploying and securing a Gitlab instance, it makes sense to keep going in this vein.
Installing Gitlab CI
As the instructions may change, here is the Gitlab Runner repo:
This will setup the hooks and listeners for our commits to start a build.
I elected to install Docker on the Gitlab server to isolate CI builds from affecting the server.
curl -sSL https://get.docker.com/ | sh
this gives us more flexibility when creating our .gitlab-ci.yml configurations for our projects.
When the installer asks for the registration details, you’ll find that here in your Gitlab install: Project > Settings > Runners.
Runners
Runners break down a build into three main phases:
- Build
- Test
- Deploy
Using our knowledge of Docker we can build isolated and reproducable builds. Here’s the one I’ve created for this blog:
.gitlab-ci.yml
image: ruby:2.3
stages:
- build
- test
- deploy
before_script:
- apt-get update >/dev/null
- apt-get install -y locales >/dev/null
- echo "en_US UTF-8" > /etc/locale.gen
- locale-gen en_US.UTF-8
- export LANG=en_US.UTF-8
- export LANGUAGE=en_US:en
- export LC_ALL=en_US.UTF-8
- bundle install --jobs $(nproc) --path=/cache/bundler
build-and-lint:
stage: build
script:
- scripts/cibuild
only:
- master
The encoding changes you see are a solution to Invalid byte sequence in US-ASCII - an issue I only saw in my Ubuntu environments, not locally on OS X.
cibuild
#!/usr/bin/env bash
set -e # halt script on error
bundle exec jekyll build
bundle exec htmlproofer _site
based on Jekyll’s recommendation: Jekyll CI
Validation Gotchas
-
<img>
tags need analt=
-
Markdown anchor links are all lowercase with no spaces, periods, or question marks.
a header like # .gitlab-ci.yml
resolves to #gitlab-ciyml
and ## Installing Gitlab CI
resolves to #installing-gitlab-ci
Luckily, the htmlproofer
gem catches these sorts of breaks as well as many others.
Commit > Push > Build
Once we’re ready to commit we merge our feature branched article into trunk and run git push gitlab master
we see the build kicking off:



oops…
It appears our linter caught a broken link in the site. Lets fix that.


Troubleshooting
Invalid byte sequence in US-ASCII
By default, the ruby:2.x
Docker image uses US-ASCII instead of UTF-8, which will cause validation errors when linting the generated site for errors.