No scheduler? No Cron? No problem... use GitHub Actions
Some hosting platforms, especially serverless, do not have a scheduler or Cron capabilities, but there are other ways to achieve this.
Most apps need some sort of scheduling functionality. This could be to send emails, check external services for new data… the list goes on. Whilst modern hosting providers offer great scalability, they may not have Cron capabilities, especially when they are serverless.
There is another alternative, the external trigger! You can create an API endpoint on your app that does what it needs to do. Then you can test this by visiting the URL in your browser. If all is working well, the next step is to automate it with something, rather than visit it manually. I think this “something” could be a GitHub Action. Yes a GitHub Action is usually triggered by an event on GitHub, but they do have scheduling functionality just a like Cron job on Linux.
on:
workflow_dispatch:
schedule:
- cron: 0 1 * * *
I won’t go into a lot of detail about the Cron functionality and how to configure the scheduled time because there is already a lot of great content out there on that - so note that it is super customisable.
As a brief overview:
The first value is the minute
The second is hour
The third is day
The forth is month
The firth is day of the week
The `*` is for any value on that item, so the Cron in the above example will run at 1am every day.
I know what some of you are thinking, “But anyone can visit this URL!” Yes they can and I will share a way to protect this later on.
Then in the GitHub Action, you can make a http request. There are various ways to do this, such as Curl, Javascript and more, in the GitHub Marketplace. After testing a few, I actually decided on an Action in the Marketplace `tyrrrz/action-http-request`.
With all this added together this is what the whole GitHub Action looks like:
name: Run checks
permissions: read-all
on:
workflow_dispatch:
schedule:
- cron: 0 3 * * *
jobs:
api:
runs-on: ubuntu-latest
steps:
- name: hit api
uses: tyrrrz/action-http-request@master
with:
url: "https://healthcheck.eddiehubcommunity.org/api/system/checks?token=${{ secrets.API_TOKEN }}"
You will notice that the URL has a token param appended to it. This is how I secure the API endpoint in my application. The first step my app does for this API endpoint is to check that the token sent in matches the token my app is expecting. That way the API endpoint can’t be used by anyone.
In my NextJS code I have the following:
if (request.nextUrl.searchParams.get("token") !== process.env.API_TOKEN) {
return Response.json({ error: "denied" }, { status: 401 });
}
That’s it, you now have a scheduler/crontab for your app. You can also add more at different frequencies if required.
Here is a real world example on GitHub:
https://github.com/EddieHubCommunity/HealthCheck/blob/main/.github/workflows/checks.yml
If you prefer to watch a video on this topic then take a look at: