Auto-publish future posts with JAMstack on Netlify and CircleCI 2.0 scheduled jobs

Hugo Di Francesco - Apr 23 '19 - - Dev Community

Static site generators like Hugo, Jekyll, Hexo, Gatsby or other JAMstack alternative are a great option to run your blog on.

One of the earliest and possibly most painful issues you will come across is “How do I schedule content to publish for later?”.

In the traditional database-backed blog site, using WordPress or Ghost for instance. The posts are retrieved on access (at run-time in Computer Science-speak). To have a post that only starts appearing after a certain date is as simple as having a field with a “publishedAt” date, and some code that checks whether that field is before or after the current date.

Enter the JAMstack. It doesn’t run using a classic PHP/Node.js/Python/Rails server-side component backed by a relational or non-relational database.

JAMstack: Modern web development architecture based on client-side JavaScript, reusable APIs, and prebuilt Markup.

See jamstack.org and jamstack.wtf

Instead the JAMstack does the bulk of the processing work at build-time (as opposed to runtime ). This tends to have a bunch of benefits like improved cache ability, higher leverage of a CDN (Content Delivery Network) which all contribute to a snappier experience.

The downside of this ahead-of-time computation of all the pages on the site is that there isn’t an obvious way to do “scheduled” posts. To make a post appear, you need to re-build the site after its “publishedAt” date so that it’s included in the build pages.

This post goes through how to achieve this using modern tools. Namely CircleCI 2.0 and Netlify (which is a hosting platform specialised in JAMstack sites).

Table of Contents:

Enable Netlify build hooks

Pre-requisite: your site must be deployed using Netlify

Create a build hook by going to https://app.netlify.com/sites/{{your_site_name}}/settings/deploys#build-hooks

Netlify Build hook config

Once you click “Save”, you now have a new deploy webhook, which you can open and copy the curl -X POST -d {} https://api.netlify.com/build_hooks/{{your_hook_id}}.

Netlify hook created,

Create a scheduled CircleCI job to re-deploy your site

Pre-requisite: your site must be set up with CircleCI which you can do following the official “Getting started” guide

We’ll add a job to trigger Netlify builds and schedule it by amending your .circleci/config.yml (see the final config.yml)

Trigger Netlify deploys from CircleCI

See the config.yml in full

In the jobs section, add a deploy or trigger_deploy job that uses any arbitrary CircleCI image (all CircleCI docker images contain curl which is what we’ll use to trigger the build). In config-speak that’s a docker key that contains eg. - image: circleci/node:latest.

In terms of steps for the deploy job, all we need is the curl command that we previously copied. That’s - run: curl -X POST -d {} https://api.netlify.com/build_hooks/{{your_build_hook_id}}.

Schedule the CircleCI job for daily execution

See the config.yml in full

To schedule a CircleCI job, we’ll need to look at the workflows sections of the .circleci/config.yml.

In this section we should add an autopublish workflow with triggers set to schedule with a cron expression and a branch filter, and the job set to - deploy (or whatever other name we used in the previous section):

    triggers:
      - schedule:
          cron: "00 7 * * *"
          filters:
            branches:
              only:
                - master
    jobs:
      - deploy
Enter fullscreen mode Exit fullscreen mode

Here’s the full workflow block:

workflows:
  version: 2
  autopublish:
    triggers:
      - schedule:
          cron: "00 7 * * *"
          filters:
            branches:
              only:
                - master
    jobs:
      - deploy
Enter fullscreen mode Exit fullscreen mode

CircleCI runs on UTC time, so the CRON job will run at 7am UTC, which is fine for me since I’m in the UK where we’re always give or take a couple of hours from UTC. For someone in the US, you may want 7 or 8am your time, which would be something like 12pm (for EST).

You can play with the CRON expression at crontab.guru, but for daily auto-publishes, you should just play around with the 00 7 part of the expression. If you want hourly deploys, you would get rid of the 7 since that denotes the hour, and go with something like 00 * * * *.

Full .circleci/config.yml

version: 2
jobs:
  deploy:
    docker:
      - image: circleci/node:latest
    steps:
      - run: curl -X POST -d {} https://api.netlify.com/build_hooks/{{your_build_hook_id}}

workflows:
  version: 2
  autopublish:
    triggers:
      - schedule:
          cron: "00 7 * * *"
          filters:
            branches:
              only:
                - master
    jobs:
      - deploy
Enter fullscreen mode Exit fullscreen mode

unsplash-logo
Estée Janssens

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .