Building a Blog Part 3 - Continuous Integration with Gitlab CI
Table of Contents
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.