Utilizing Gulp with Jekyll

I’ve been working on some visual and technical improvements to my blog lately. I set out with the goal of making things faster, improving my build tools, and utilizing a Service Worker and Google AMP. My blog uses Jekyll, and is hosted using Github pages, so there were some limitations that I had to consider while setting out to achieve these things. In the first part of this series I explain how I setup Jekyll to use a popular taskrunner called Gulp, and the reasons behind it.

Using the 'gh-pages' branch

Jekyll can be extended and built upon using plugins known as gems, however only those on an approved whitelist can be utilized when hosting with Github. While working towards my implementation goals I ran into this restriction constantly as there were a few gems I wanted to try out.

Montezuma eating Octocat

You can setup Github pages to work two ways, either you can have a personal page, or you can have a project page. Personal pages run out of their own repository in the master branch, as long as it’s named username.github.io, while project pages run out of the gh-pages branch on any repository. What I wanted to do was maintain my uncompiled site in the master branch, and then send the locally compiled site to the gh-pages branch with a taskrunner, allowing me to get around the restrictions on gems. In my case I had to convert my repository from a personal page to a project page, which was just a matter of renaming it and setting up the gh-pages branch. I use a domain name, but was pleasantly surprised to find that I didn’t have to modify any DNS records to achieve this.

Setting up npm

I decided to use Gulp as my task runner, not only am I most familiar with it but there’s also this really handy package called gulp-gh-pages by shinnn which does exactly what I’m looking for. Before getting started I setup my project to work with Node Package Manager (npm) so I could easily install or update the Gulp package. In order to do this you need to have NodeJS installed, from there you can run npm init within your repository to create a package.json file. After following the prompts you’ll have something which looks similar to this.

{
  "name": "james-ives-portfolio",
  "version": "1.0.0",
  "description": "Portfolio of James Ives, Full-Stack Developer.",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "repository": {
    "type": "git",
    "url": "git+https://github.com/example/example.git"
  },
  "keywords": [
    "portfolio",
    "jekyll"
  ],
  "author": "James Ives",
  "license": "ISC",
  "bugs": {
    "url": "https://github.com/example/example/issues"
  },
  "homepage": "https://github.com/example/example#readme",
  "devDependencies": {
  }
}

Within the devDependencies object you can place node packages that are required by your project. In here you can place whatever you like, but in my case I wanted gulp and gulp-gh-pages, as those are what I was going to use to deploy my site.

"devDependencies": {
  "gulp": "^3.9.1",
  "gulp-gh-pages": "^0.5.4"
}

Once you’ve saved the package file you can then run npm install to gather all of the dependancies. While this is running it’s a good idea to add the node_modules directory to your .gitignore file as you don’t need to store all of the dependancies inside your repository. If you wanted to install this project on another computer you can simply run the install command again.

Gulp Time

With the dependancies for gulp and gulp-gh-pages downloaded, you can now setup the taskrunner. Create a file called gulpfile.js and import the packages. You can then add the task to actually deploy your page to Github. In the following code replace _site with the directory your site gets built to when you run jekyll build.

const gulp = require('gulp');
var ghPages = require('gulp-gh-pages');

gulp.task('deploy', function() {
  return gulp.src('./_site/**/*')
    .pipe(ghPages());
});

If you use two factor authentication with Github you probably use an SSH key, if so you’ll need to modify it to include the SSH path for your repository.

const gulp = require('gulp');
var ghPages = require('gulp-gh-pages');

gulp.task('deploy', function() {
  return gulp.src('./_site/**/*')
    .pipe(ghPages({
      "remoteUrl" : "git@github.com:/example/example.git"
    }));
});

If everything is setup correctly you should now be able to run gulp deploy to automatically send your compiled Jekyll site to the gh-pages branch of your repository. From here you should now be able to add a gem dependency to your _config.yaml file even if it’s not on the Github whitelist. As the site is compiling locally you no longer have to worry about Github throwing a compile error.

Up Next: Google AMP

Gulp is a really useful tool to have in your arsenal, while the implementation in this post is minor you can utilize it for much more than just this. I highly recommend checking out the official documentation and browsing the vast amount of plugins available for it, all of which you can now utilize in your build tools.

If you have any questions or comments please feel free to reach out to me on Twitter, LinkedIn, or you can send me an email using my contact form.