Lesson 6 / 25
Scheduled Workflows
Cron in UTC.
Five-field cron, best effort
The schedule trigger uses five-field cron syntax in UTC. Scheduled runs use the default branch's workflow file, can be delayed during busy periods, and are disabled automatically in public repositories after a long period without activity. Use schedules for nightly builds, dependency audits and cleanup. Avoid the top of the hour, when load is highest, and make scheduled jobs idempotent.
Errors caught by actionlint, run
I checked this workflow with actionlint 1.7.12 (actionlint -oneline .github/workflows/broken.yml); the output and exit code are copied from that run. actionlint validates syntax, expressions, job dependencies and known actions offline; shellcheck was not installed, so shell scripts inside run: were not linted. The workflow was not executed on GitHub. actionlint finds three mistakes: hour 25 in the cron expression, a misspelled matrix property (nodee), and a needs: reference to a job that does not exist (biuld).
name: Broken
on:
schedule:
- cron: "0 25 * * *"
jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
node: [20, 22]
steps:
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.nodee }}
deploy:
needs: biuld
runs-on: ubuntu-latest
steps:
- run: echo deploying
Output:
.github/workflows/broken.yml:5:13: invalid CRON format "0 25 * * *" in schedule event: end of range (25) above maximum (23): 25 [events]
.github/workflows/broken.yml:16:29: property "nodee" is not defined in object type {node: number} [expression]
.github/workflows/broken.yml:17:3: job "deploy" needs job "biuld" which does not exist in this workflow [job-needs]
(exit code 1)Convert to UTC
A 09:00 IST job is 03:30 UTC: write "30 3 * * *".
Quick check: Which time zone do GitHub Actions cron schedules use?
- US Pacific time
- The repository owner's local time
- The runner's local time
- UTC
Answer
UTC — Always UTC.