Automatic Publishing With Jigsaw, Netlify and GitHub Actions cover image

Automatic Publishing With Jigsaw, Netlify and GitHub Actions

Published by James Brooks on January 21, 2020


When I first setup this blog (just a couple of weeks back) I was using a combination of; Tighten Jigsaw, GitHub Actions & Pages. That setup allowed me to initially get my blog up and running very quickly, letting me focus solely on the content. However, soon after I published that post @the_nabeelahmed suggested using Netlify over GitHub Pages and provided me with the minimum configuration details needed to get Netlify working.

As I had some time that evening, I checked out Netlify and was genuinely able to get my blog published and switched over in a matter of minutes. That is a developer experience I loved.

Now, I know that some of you are saying / screaming:

James, you've only just started blogging, focus on the content and stop optimizing early!

To you, I say: thanks for the concern, but I'm optimising my writing workflow to allow me to focus on the content whilst reaping all the benefits of a static site and in doing so, I'm able to write about my experiences. Yes, I could use Wordpress, but that requires even more work to customise to my liking (and I never want to use hosted Wordpress ever again).

I may have switched to Netlify but it wasn't a case of disliking GitHub Pages! Here are my reasons for switching:

 The Current Setup

Okay, so let's break down the current setup and how it works. I can't see that the core of this is going to change any time soon, because I'm extremely happy with how frictionless it all is.


I configured the default deploy context (through the Netlify UI) with the following:

Deploy Contexts:

Within my blog source, I also have a netlify.toml file which contains more configuration options. It looks like this:

    environment = { PHP_VERSION = "7.2" }

    command = "npm run staging"
    publish = "build_staging"

    command="npm run production"

By default everything will build in the staging environment, but for production builds, I use the production environment.

Build Image Selection:

I'm using Ubuntu Xenial 16.04 (default) because it's the latest build image Netlify has. I'd opt for 18.04 if I could.

Build Hook:

I created a custom build hook which we'll use later to trigger a scheduled automatic deployment.

 Jigsaw Requirements

I want to be able to write ahead of myself and by this, I mean that I want to write a post that's scheduled for a date in the future and have GitHub Actions publish it automatically. To make this happen, I made a couple of small changes to the Jigsaw config files.

Firstly, I needed to update the config.staging.php file so that the baseUrl is set to env('DEPLOY_URL'). This means that when Netlify deploys a branch preview, I can navigate the blog correctly. DEPLOY_URL is an environment variable set by Netlify.

Next, I needed to add a filter to my posts collection in my base config.php array:

'collections' => [
  'posts' => [
    'author' => 'James Brooks',
    'sort' => '-date',
    'path' => 'blog/{filename}',
    'filter' => function ($post) {
      return true;

This is needed because it appears that Jigsaw does not merge configs together, so we need a dummy filter to override later.

Finally, in the config.production.php config, we override the filter method to check the publish date is in the past:

'filter' => function ($post) {
  return Carbon::parse($post->date)->isPast();

And now I'm able to use the date field on any of my posts as the published date.

GitHub Actions

My workflow for publishing is now:

This is my ./github/workflows/publish.yml file:

name: Publish Posts

    - cron: "0 8-22 * * *"

    runs-on: ubuntu-latest
    - name: automerge
      uses: "pascalgn/automerge-action@75ca70eb25b33837664f25d6270d20b629d23614"
        GITHUB_TOKEN: "${{ secrets.GH_TOKEN }}"
        MERGE_LABELS: "finished"

    - name: scheduled-deploy
      if: github.event_name == 'schedule'
      uses: wei/curl@master
        args: -X POST -d {} "${{ secrets.NETLIFY_BUILD_HOOK }}"

For this to work, you need to create a new secret in your repository for GH_TOKEN, which is a personal access token with repo permissions. I also created a secret of NETLIFY_BUILD_HOOK which contains the URL that Netlify generated for us earlier.

GitHub Actions will automatically run the workflow every hour between 8AM and 10PM (which is typically when I'd want to write a post)! Since any changes I make to the source branch will automatically be deployed, this covers everything I need! By doing this, Netlify is essentially regenerating any draft posts every hour.

I'm particularly happy with this configuration for a few reasons:

  1. I can adjust the schedule as I see fit and run automerge more or less frequently if I need.
  2. I can treat pull requests as drafts until it has the finished label.
  3. Any posts that are merged, but we're not yet at their publish date will automatically build and become published with no manual deployments needed.

Let me know if you use this technique or something similar at @jbrooksuk.

Interested in hearing more from me?
Sign up to my newsletter to hear more from me in the future.