Automated deployment of Jekyll projects to GitHub pages using Kickster and Circle CI

I am a huge Jekyll fan, I used it for over 30 projects (or I like to think so) and it’s still my favorite static site generator. Over the past years I collected best practices and set up a project template that helps me kickstart my new projects faster.

Next to using Jekyll I love working with awesome plugins like Assets, sitemaps, multiple languages and many more. Sadly GitHub pages does not support many out of the box so I decided to build Kickster which allows you to use any plugin and still deploy with ease.


What is this about?

Kickster is a simple gem that scaffolds a new Jekyll project packed with useful tools to kickstart your new web projects. It contains the following tools:

  • Autoprefixer for CSS vendor support (so no more vendor prefixing in your CSS, Autoprefixer takes care of this automatically).
  • Bower, a package manager for easy management of vendor frameworks, libraries, assets and utilities.
  • Circle CI for automated testing and deploying.
  • HTML Proofer for validation of your HTML. Used by Circle CI during automated tests.
  • Jekyll, duh.
  • Jekyll Assets for asset compression.
  • Jekyll Sitemap for automatic generation of your sitemap.
  • Influences from HTML5 Boilerplate, a best practice front-end web template.

So how does this work?

Setting up is very simple with Kickster, just run the following commands in your command line:

# Install the gem
gem install kickster
# Execute gem and scaffold Kickster template folder
kickster new site_name
# Move into your project folder and setup your environment with
bin/setup

You can now enjoy building you project rather then having to focus on setting up everything yourself. Don’t forget to add your project repository on Circle CI to enable automated testing!

Deploying is even more simple. Once you are done with changing your website code, you push it to your working branch, check if tests succeed on Circle CI and if everything is ok run the following command:

bin/deploy

That’s it, enjoy your nicely build project on GitHub pages! Keep reading if you want to take it one step further.


Automated deployment with Circle CI

Automated deployment is by default not included in your Kickster generated Jekyll project as it requires some more manual work. However it is not rocket science and can be setup with 3 easy steps.

1. Copy the required automated deploy script

Copy the following automated script inside your project bin folder:

#!/bin/bash

# Automated deploy script with Circle CI.

# Exit if any subcommand fails.
set -e

# Variables
ORIGIN_URL=`git config --get remote.origin.url`

echo "Started deploying"

# Checkout gh-pages branch.
if [ `git branch | grep gh-pages` ]
then
git branch -D gh-pages
fi
git checkout -b gh-pages

# Build site.
bower install
bundle exec jekyll build

# Delete and move files.
find . -maxdepth 1 ! -name '_site' ! -name '.git' ! -name '.gitignore' -exec rm -rf {} \;
mv _site/* .
rm -R _site/

# Push to gh-pages.
git config user.name "$USER_NAME"
git config user.email "$USER_EMAIL"

git add -fA
git commit --allow-empty -m "$(git log -1 --pretty=%B) [ci skip]"
git push -f $ORIGIN_URL gh-pages

# Move back to previous branch.
git checkout -
bower install

echo "Deployed Successfully!"

exit 0

This script does the following things:

  1. Deletes your gh-pages branch locally if you already have one, so we can start with a clean one.
  2. After moving to a fresh gh-pages branch we install all project dependencies and generate your project inside a temp folder.
  3. Next we will be removing all files except the generated site directory and required git folders.
  4. When our folder is stripped from unrequired files we move our generated site in the root folder and remove the empty generated site folder.
  5. Now our project is ready to be deployed to the gh-pages branch.
  6. After deploying we move back to your previous branch and install back our required dependencies.

2. Update Circle CI configuration

We need to expand our circle.yml file to support deploy hooks on the master branch. So when we merge a pull request inside our master branch it will run the deploy script we just added. Update your circle.yml file with the following config:

machine:
environment:
USER_NAME: <your-github-username>
USER_EMAIL: <your-github-email>
ruby:
version: 2.4.0

dependencies:
pre:
- ./bin/setup

test:
post:
- bundle exec jekyll build
- bundle exec htmlproof ./_site --only-4xx --href-ignore "#"

deployment:
production:
branch: master
commands:
- ./bin/automated

As you can see we added some environment variables to authenticate ourselves and added the deploy script. Don’t forget to fill in your GitHub details and enable your repository in Circle CI!

3. Enable Circle CI

Make sure you enabled your repository on Circle CI. After that we have to create a Read/Write deployment key. All 3 steps can be found here.

In short you have to:

First create a ssh key on your computer: ssh-keygen -t rsa -b 4096 -C "your_email@example.com" (leave the passphrase empty).

Now create a new deploy key in your GitHub project and paste the public key in there and make sure you “Allow write access”.

Lastly create a new SSH key in the “SSH Permissions” tab under your project settings in Circle CI and paste the private key in there with the hostname: github.com.

That’s it, from now on when you merge a branch inside your master branch it will run its tests and on success it will deploy your website to GitHub Pages!

Prefer to use Travis CI? I added all info to setup automated deployment with Travis here.

Make sure to give it a try and let me know how it went! I’m pretty sure it will be a nice addition as it provides a worry-free deploy and setup to your Jekyll projects.

Kickster on GitHub

If you have any questions or feedback, join me on the Gitter channel or tweet me!