Tighten’s Jigsaw, GitHub Pages and GitHub Actions
This blog was previously powered by Tighten’s Jigsaw project. Even though it’s no longer used, if you’re thinking about starting your own blog, I can still highly recommend it.
Since Jigsaw generates a static website, I chose to host it with GitHub Pages as a "user site" as they allow for top-level domains. GitHub Pages only serve static sites, but as Jigsaw is a dynamic system we need to generate the site. I was able to automate this process with GitHub Actions. It took some trial and error (read: a lot of wip commits) but I was finally able to make it work and wanted to share this setup as I think it’s pretty sweet.
I’ll break this down into two sections, the first, using Jigsaw and GitHub Pages and the second, publishing with GitHub Actions.
Jigsaw & GitHub Pages
Jigsaw provides instructions on how to use GitHub Pages, but it’s written for project sites and not user sites. If you’re not sure why this is a problem, it’s because user sites require that the site contents are in the master
branch, whereas repository sites default to gh-pages
- though that can be changed.
To get this working, I setup Jigsaw under a source
branch which contains all of the code, assets and post content. I then push the contents of the build_production
directory to the master
branch, which GitHub happily serves up for you to read.
It’s a small change, but it may not immediately be obvious, so it’s worth clarifying!
Jigsaw & GitHub Actions
Jigsaw is really, really good but I’m lazy and don’t want to manually be building my website, committing and publishing it after each post.
Admittedly, it took me a lot of time to figure these steps out, but now I’m able to write a new post and have GitHub automatically build and publish it for me!
I created a new workflow under .github/workflows/build-publish.yml
with the following:
name: Build & Publish
on:
push:
branches:
- source
schedule:
- cron: "0 2 * * 1-5"
jobs:
build-site:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Install Composer Dependencies
run: composer install --no-ansi --no-interaction --no-scripts --no-suggest --no-progress --prefer-dist
- name: Install NPM Dependencies
run: npm install
- name: Build Site
run: npm run production
- name: Create CNAME File
run: echo "james.brooks.page" >> build_production/CNAME
- name: Stage Files
run: git add -f build_production
- name: Commit files
run: |
git config --local user.email "[email protected]"
git config --local user.name "GitHub Actions"
git commit -m "Build for deploy"
- name: Publish
run: |
git subtree split --prefix build_production -b master
git push -f origin master:master
git branch -D master
It may look complicated, but we can break it down.
- We tell GitHub to only run the workflow on pushes to the
source
branch. I also opted to automatically run the workflow at 2PM Monday - Friday, just in case 🤷🏻♂️ - Next we’re installing the Composer and NPM dependencies.
- Once the dependencies have been installed, we build the site using the production environment configuration.
- Optional! I’m using a CNAME on GitHub Pages so that I can use my own domain. I create a new file and fill it with the domain name I want to use.
- I forcefully stage the
build_production
directory, this is because Jigsaw defaults to ignoringbuild_*
directories from Git and I don’t want to change this and accidentally publish it into thesource
branch. - Next we configure Git’s email and name, I chose to use GitHub Actions as the author so that I know it’s an automatic commit. We then commit the contents with a pre-defined commit message.
- Finally, we’re going to publish the site by pushing the changes from within the GitHub Action itself! This is a bit complicated if you’re not confident with Git, but let’s try to keep it simple. We create a subtree of the
build_production
directory and pushing it into a temporarymaster
branch. Now we can force push the branch to GitHub and clean up by deleting themaster
branch1.
And that’s it, I’m now able to write new blog posts without my laptop (using just the GitHub website) and have them immediately published for me.
Let me know @jbrooksuk if you’re using this technique or have any suggestions on how to improve it.
Footnotes
- Because we’re force-pushing to
master
from a branch which contains only one commit, all history is lost for the published website. This is a trade-off that I’m happy with because the real history is in thesource
directory.