Guides & Tutorials

How to Schedule Deploys with Netlify

👋 Introduction

So, you’ve built a website / app and you’ve gotten it to successfully deploy to Netlify. Huzzah! 🎉

While it’s amazing that Netlify automatically deploys websites whenever code is pushed, sometimes you need deploys to happen on a more regular interval. A common example of this is when you have a statically generated site that has new content every week.

Wouldn’t it be nice if you didn’t have to manually log in into your Netlify dashboard every X days to manually deploy your site? There has to be a better way, right? Why yes indeed, cause you can with Netlify Scheduled Functions!

What are Netlify Scheduled Functions?

Netlify Scheduled Functions are a special type of serverless function that can be run on a regular and consistent schedule. Some of you might also know this type of scripting to be known as a CRON job.

At the time of this blog post, Netlify Scheduled Functions are considered experimental, so you’ll need to enable them within Netlify Labs on your account to utilize it.

The Anatomy of a Scheduled Function

A Netlify Scheduled Function has two primary parameters:

  1. CRON Expression: A string that often defines how often something should be run
  2. Callback Function: A function that will be called at this scheduled interval

Here’s an example:

const { schedule } = require('@netlify/functions')

const handler = schedule('* * * * *', () => {
  console.log('Print this message every hour.')
})

How do I use it?

There are two primary ways to use Netlify Scheduled Functions:

  1. Directly in your serverless function
  2. Configure it within your netlify.toml file

In this blog post, I’ll be focusing on defining your scheduled functions in your serverless functions since it provides a more cohesive approach to comprehension and maintenance.

If you’d like to learn more about the configuring it inside of netlify.toml, you can check out the official docs on how to do so.

Prerequisites

Before we get started, it’s recommended to have the following:

If not, be sure to check out any of the linked resources to learn more!

Setup

Installing Dependencies

To get started with Netlify Scheduled Functions, you’ll need to install the following dependencies in your project:

npm install @netlify/functions
npm install node-fetch

This is required because:

  1. @netlify/functions -We’ll need to import the scheduled function method in order to define a specific interval we want our function to run at
  2. node-fetch - Serverless functions are run in a Node environment and don’t have a built-in ability to make async calls, so we need this library to run our POST request

In addition, with so many tools using ES Modules, you’ll want to add the following configuration to your netlify.toml that configures the node_bundler to use esbuild.

📄 netlify.toml

[functions]
  node_bundler = "esbuild"

Configure a build hook

In order to trigger a build on Netlify, you’ll need something called a build hook, which is a fancy term for a URL that will tell Netlify to deploy your site. They usually look something like this:

https://api.netlify.com/build_hooks/abc123def456

If you run a POST request on a build hook, this will return a response on whether it successfully triggers a build or not.

To configure this:

  1. Go to your site’s Netlify Dashboard (e.g., https://app.netlify.com/sites/YOUR_SITE_NAME/)
  2. In the top nav, go to Site settings
  3. On the left sidebar, open up the Build & deploy menu
  4. This will open up a submenu that defaults you to the Continuous deployment section
  5. Within this page, you’ll find a Build hooks section that will allow you to create a build hook with the Add Build Hook button.

Once you fill out the name of the build hook (which is for tracking purposes only) and which branch you want the build hook to trigger, you should now have a URL that we’ll be calling later on in this post.

Scaffolding a serverless function to deploy your site

Since there are many frameworks and architectures out there, we’re going to focus on creating a generic serverless function so that it works for any app! To do this, we’ll create a new JS file called scheduled-deploy.js.

📄 /netlify/functions/scheduled-deploy.js

const fetch = require('node-fetch')

// This is sample build hook
const BUILD_HOOK = 'https://api.netlify.com/build_hooks/abc123def456'

const handler = async () => {
  await fetch(BUILD_HOOK, {
    method: 'POST'
  }).then((response) => {
    console.log('Build hook response:', response.json())
  })

  return {
    statusCode: 200
  }
}

export {
  handler
}

Now that everything is set up, let’s learn how to make it run on a scheduled interval!

Add scheduling to your serverless function

First things first, let’s go ahead and import our schedule helper function from @netlify/functions.

const fetch = require('node-fetch')
import { schedule } from '@netlify/functions'

// This is sample build hook
const BUILD_HOOK = 'https://api.netlify.com/build_hooks/abc123def456'

const handler = async () => {
  await fetch(BUILD_HOOK, {
    method: 'POST'
  }).then((response) => {
    console.log('Build hook response:', response.json())
  })

  return {
    statusCode: 200
  }
}

export {
  handler
}

Now that we have our helper function, we need to determine what interval we want our function to run at.

Defining the CRON expression

If you’ve ever explored scheduling tasks in programming, odds are pretty good you ran into a syntax that looked something like * * * * *, which is quite cryptic at first glance. To be frank, CRON expressions is something that I always have to look up whenever I use it, so don’t feel pressure to memorize what it means.

As a crash course on what’s going on though, a CRON expression is a string that typically contains five values separated by a space.

*      *       *      *        *
min    hour    day    month    day
             (month)          (week)

Without going into depth, at a high level, the * is essentially a wildcard that says “it can be any value.” So in the example above, the CRON expression states that the function should run:

  1. At any minute
  2. At any hour
  3. At any day (of the month)
  4. At any month
  5. At any day (of the week)

Which is another way of saying: “Run this function every minute.”

That’s not very realistic, so let’s assume that we need to run our function twice a week on Monday and Friday at midnight. So translating this to CRON expression, we need it to run on:

  1. 0 - At minute zero (i.e., XX:00)
  2. 0 - At hour 00 (i.e., 00:XX)
  3. * - Any day of the month
  4. * - Any month of the year
  5. 1,5 - On Mondays (i.e., 1) and Fridays (i.e., 5)

Put that all together and it looks like: 0 0 * * 1,5!

There’s more you can do when it comes to writing CRON expressions, but that would be an entire blog post in it of itself. For more info, check out crontab guru for a tool to help you write CRON expressions.

Putting it all together

Now that we have our CRON expression, it’s time to invoke our imported schedule function and pass in the appropriate parameters. When we put it all together, your code should now look like:

import fetch from 'node-fetch'
import { schedule } from '@netlify/functions'

// This is a sample build hook URL
const BUILD_HOOK =
  'https://api.netlify.com/build_hooks/abc123def456'

// Schedules the handler function to run at midnight on
// Mondays, Wednesday, and Friday
const handler = schedule('0 0 * * 1,5', async () => {
  await fetch(BUILD_HOOK, {
    method: 'POST'
  }).then(response => {
    console.log('Build hook response:', response)
  })

  return {
    statusCode: 200
  }
})

export { handler }

And that’s it. Once you deploy this to your site, you’ll have scheduled deploys up and running! 🎉

Next Steps

Like any tool or technique, this is just the tip of the iceberg. To learn more, be sure to check out the offical docs for Netlify Scheduled Functions.

Thanks for reading and here’s to hoping your life is a little easier now that you’ve automated your deployments! 🙌

Keep reading

Recent posts

How do the best dev and marketing teams work together?