Using GitHub Actions as a (web)cron
Suggestions on using the schedule property
tl;dr; Check out an example of a web cron on GitHub.
GitHub Actions are pretty great. I use them to run tests for every git push
, and make sure that tests pass before a PR can be merged. Before that I've used TravisCI, CircleCI, and CodeShip. While there's nothing necessarily wrong with them (they work, are stable, well-documented, and have free and paid plans), I like the simplification of keeping everything in GitHub, which is where the code has always been, anyway.
For many personal and professional cases, I have some jobs that need to run on a schedule, and for simplicity (and also because most of them are "serverless" now), they can usually be triggered with a GET
or POST
request, with some sort of authentication token, and I've used Zen Cron for over a year for that, and have no complaints at all (it is something I've built).
However, pretty much like CI, the idea of getting such jobs to not have to be "outsourced" (especially with the "secret" variables) and simply run from within where the code and deployment exists was just too enticing. Luckily, it's really easy and you just need to add something like:
on:
schedule:
# Every Monday at 1:05am UTC
- cron: '5 1 * * 1'
On your GitHub workflow file.
For making an HTTP request, you can use curl
! Something like this:
- run: |
curl -X "POST" "https://example.com/api/jobs/cleanup" \
-H 'Content-Type: application/json; charset=utf-8' \
-H 'Authorization: Bearer ${{ secrets.JOB_API_KEY }}' \
-d $'{ "someKey": "someValue" }'
To add secrets, you just need to use GitHub's secrets tab in your repo.
All together, a simple job workflow file can look like:
name: Job - Cleanup
on:
workflow_dispatch:
schedule:
# Every Monday at 1:05am UTC
- cron: '5 1 * * 1'
jobs:
job-cleanup:
runs-on: ubuntu-latest
steps:
- run: |
curl -X "POST" "https://example.com/api/jobs/cleanup" \
-H 'Content-Type: application/json; charset=utf-8' \
-H 'Authorization: Bearer ${{ secrets.JOB_API_KEY }}' \
-d $'{ "someKey": "someValue" }'
The workflow_dispatch
above ensures that you can trigger (and easily test) the job manually from the GitHub Actions UI.
If you don't want to run a job via a URL, you can simply checkout your code, install dependencies and run a command, like:
name: Daily Cron
on:
workflow_dispatch:
schedule:
# Daily, 1:15am UTC
- cron: '15 1 * * *'
jobs:
daily-cron:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- uses: actions/setup-node@v1
with:
node-version: 12.x
- run: |
make install
make run/daily-cron
env:
SOME_ENV_VALUE: ${{ secrets.SOME_ENV_VALUE }}
NOTE: One important thing to note is that I still use Zen Cron for very frequent web crons, because anything that runs more than once per hour can get expensive on GitHub (by default it'll just stop working once you reach the limits, but you can set a monthly limit/cap on GitHub Action minutes).
I hope you enjoy it.
Thank you so much for being here. I really appreciate you!