Working Offline with Github Pages
How (not) to tailor your Gemfile, to ensure your local Jekyll environment uses Github Pages' plugin versions even when offline.
Update - 8 May 2017
Whilst the below is a novel solution to this problem, I have since found a far simpler solution (discussed at the end of the article). There are merits for each, and it provides for interesting discussion. Have a read and judge for yourself?
The Problem
When you run a (Jekyll) GitHub pages site locally, how do you ensure that you are using the same gems (plugins) and versions as will be used on GitHub?
Further - what happens if you don’t have internet access, and can’t check what versions Github is currently using?
The [edit: A Potential] Solution
Part A: Using GitHub’s versions locally
Solving the first part of this problem was relatively straightforward;
The above (when internet access is available) shall check to see what plugin versions GitHub is using.
Perfect.
This means that when I run my Jekyll site locally, it will behave exactly in the same way as when Github builds my site.
Except - what happens when I take my dev environment on the road, and I can’t connect to the internet?
Part B: Dealing with internet connectivity issues
Checking for internet connectivity
Solving this part, first happened after I read fotanus’ post on Stackoverflow.
This caused me to include the following function within my Gemfile:
Reverting to local cache when connectivity is unavailable
However I still needed to write some logic to:
- “Cache” the versions page (when internet connectivity exists)
- Fall back to this cache when internet connectivity does not exist
In order to “cache” this information, I simply store a ‘versions.json’ in the project root. The file gets updated whenever GitHub’s version becomes changed.
That code looks like this:
Note that I also included some printed output, so that when I run jekyll serve
I am advised whether internet connectivity was able to be established.
Finished Gemfile
The completed Gemfile:
An even simpler solution?
Update - 8 May 2017
Per earlier comment, I came across this simpler solution after posting the original article.
It’s actually possible to completely ignore this entire post, and instead make sure that you are running Jekyll via: bundle exec jekyll serve
instead of jekyll serve
.
But, you also need to make sure that you are:
- running
bundle update
at regular intervals, and - checking
Gemfile.lock
into source control.
A detailed explanation of this, can be found here: bundler.io/rationale.
Which solution should you use?
Interestingly, the two solutions work in a very similar same way, ie;
- Both solutions write a file to the project directory (versions.json / Gemfile.lock), listing out the gem versions that were utilised within the previous successful build.
- The files even look loosely the same:
As I alluded to at the start of the article; the Bundler solution is somewhat simpler and clearly more widely recognised. It also tracks changes to your local environment’s other Jekyll dependencies. For these reasons it is currently the solution I would recommend.
A further argument is that the development tenant “DRY”, can be extended to encompass “Don’t Repeat Your Framework”. Clearly the custom solution above breaches this.
That said; Bundler does require you to run bundle update
(and you must remember to do this regularly), whereas my custom (read as: “proceed with caution”) solution doesn’t require you to do this. For this reason, I’m leaving this post here as food for thought.
Comments (constructive) are welcome .