Jekyll injection

Adding date and time to a GitHub page

2021 Dec 31

It’s a problem every developer has faced (it me, I’m every developer). You make an earth-shattering edit to your blog on GitHub pages, commit, push, and refresh your browser to see the changes. But wait: are you looking at the edited page, or the old version? You watch the page build GitHub action to confirm that it completed, but has the deployment trickled all the way down yet?

The only way to really know which version you’re looking at is to add the build time or git revision somewhere on your page. Jekyll even offers the variable site.github.build_revision for the latter.

We’re going to look at a more flexible solution that can be extended to other automated page modifications, which will eventually look like this:

Build: Fri Dec 31 01:03:45 UTC 2021, revision: f7c5b70

Assuming I haven’t broken anything, you can probably see it live at the bottom of this page.

The variables injected into the page will form part of the serum that transforms Jekyll’s markdown into Hyde’s html (or do I have those codeowners backwards?).

Setup your template page source with variables to be replaced

In my example, I’m working on the _layouts/default.html page, where my footer is. You can run the injection on index.md or any other html or md (markdown) translation unit.

We don’t want the injection to modify our source code and we don’t care about version control on the output of the injection process. So, move your source file to a template that will be the source of truth:

mv _layouts/default.html _layouts/default-template.html

Make sure the template filename starts with _ or . so that it is ignored by Jekyll. We’re good since default.html is already in the _layouts folder. In the future, do all of your editing on the template file rather than the one that gets automatically modified.

Next, add the content where you’re going to inject variables into default-template.html:

<p>Build: BUILD_DATE, revision: <code>BUILD_REVI</code></p>

The variable identifiers I have chosen are BUILD_DATE and BUILD_REVI.

Be careful that these identifiers don’t appear elsewhere in your source where you want them to be literal and unmodified. Perhaps add some sigil – e.g. $VARIABLE – as an extra guard against the dumb parsing that we’re about to do.

Use sed to search and replace the template variables and generate your page source

In this example, there are some handy bash and git commands to get the data that we want to inject.

First, copy the template source file to the output destination file to be injected. Then inject the data with sed:

srce=_layouts/default-template.html
dest=_layouts/default.html
cp $srce $dest

export TZ='US/Eastern'
dat=$(date)
rev=$(git rev-parse --short HEAD)

sed -i "s/BUILD\_DATE/$dat/g" $dest
sed -i "s/BUILD\_REVI/$rev/g" $dest

Recall that the var=$(command) syntax saves the output of a bash command in a variable. The syntax for replacing search with replace globally in a file is sed -i "s/search/replace/g" file.

The underscore _ needs to be escaped in the search pattern like \_.

Setting the timezone TZ is optional, it will probably default to UTC otherwise.

Short of sigils, we can get little a extra protection by only replacing whole words that match the search pattern, by marking the beginning and ending word boundaries with \< and \> respectively:

sed -i "s/\<BUILD\_DATE\>/$dat/g" $dest

Alternatively, if you don’t want to use sed, you could generate an entire footer file with echo, cat, etc. For the Jekyll cayman theme, the footer is part of default.html, so it seems easier to use sed instead of generating all of default.html from scratch.

Build and deploy the page

Because we’re modifying the page source after every commit, we can’t use the default Jekyll GitHub pages workflow. We need to use a custom jekyll.yml workflow.

After checking out the git repo and running sed as above, place these steps in the workflow yml to build and deploy the page:

- uses: actions/jekyll-build-pages@v1-beta

- name: Deploy to github pages
  uses: JeffIrwin/github-pages-deploy-action@4.1.8
  with:
    branch: main
    folder: .

Make sure to update the branch name that you’re deploying from if it’s not main. Are you still naming branches master in 2022? 😩

I’m using JamesIves/github-pages-deploy-action to deploy. To guard against a left-pad fiasco, I forked it and used pgh git helper to keep the fork up to date.

One downside of this non-default workflow is all the junk bot commits. If you can figure out how to get rid of them, kudos to you. The default Jekyll workflow doesn’t create junk commits like this, but its yml isn’t accessible to edit and add the sed commands.

Make sure to pull the changes locally after each junk commit. If you’re like me, you’ll frequently forget to pull and end up with even more junk commits to merge the remote changes.

The full source for this site is here.