Auto-publish future posts with JAMstack on Netlify and CircleCI 2.0 scheduled jobs
Tags: blogging, jamstack, static, writing
Published: 2019-04-23 10:11:04

---
title: Auto-publish future posts with JAMstack on Netlify and CircleCI 2.0 scheduled jobs
published: true
tags: blogging, jamstack, static, writing
canonical_url: https://codewithhugo.com/scheduled-posts-circleci/
---

Static site generators like [Hugo](http://gohugo.io), [Jekyll](https://jekyllrb.com/), [Hexo](https://hexo.io/), [Gatsby](https://www.gatsbyjs.org/) or other [JAMstack](https://jamstack.org/) 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](https://jamstack.org/) and [jamstack.wtf](https://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 "My awesome hook" that deploys master branch](https://codewithhugo.com/img/netlify-webhook.jpg)

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,](https://codewithhugo.com/img/netlify-hook-created.jpg)

## 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](https://circleci.com/docs/2.0/getting-started/)

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
```

Here’s the full workflow block:

```
workflows:
  version: 2
  autopublish:
    triggers:
      - schedule:
          cron: "00 7 * * *"
          filters:
            branches:
              only:
                - master
    jobs:
      - deploy
```

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](https://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
```

[<svg xmlns="http://www.w3.org/2000/svg" style="height:12px;width:auto;position:relative;vertical-align:middle;top:-2px;fill:white" viewbox="0 0 32 32"><title>unsplash-logo</title>
<path d="M10 9V0h12v9H10zm12 5h10v18H0V14h10v9h12v-9z"></path></svg>Estée Janssens](https://unsplash.com/@esteejanssens?utm_medium=referral&utm_campaign=photographer-credit&utm_content=creditBadge "Download free do whatever you want high-resolution photos from Estée Janssens")