Convert GitHub Actions to Unix cron (POSIX/Vixie)
Move workflow schedule expressions to a real crontab: what stays identical, what timezone assumptions flip, and the Vixie extensions strict POSIX systems reject.
About this conversion
Taking a schedule out of GitHub Actions — usually to a VM, container, or self-hosted box after outgrowing hosted runners — is syntactically the quietest conversion here: the expression itself almost always survives byte-identical, same fields, same Sunday = 0. The direction matters anyway, because the assumptions flip. Workflow schedules ran in UTC; a crontab runs in the system's local time unless you set TZ or CRON_TZ. And a few things workflow files rejected become available again, while one Vixie habit can betray you on a strictly POSIX system.
What changes in this conversion
- Expressions pass through unchanged — the conversion itself is a no-op for standard field syntax.
- Timezone flips from UTC to system-local: a schedule tuned for UTC will drift by your server's offset unless the crontab's environment pins TZ/CRON_TZ.
- @-aliases become available again — a crontab accepts @daily even though a workflow file never did.
- Step syntax (*/5) is a Vixie extension, not strict POSIX — on a strictly POSIX cron, spell the minute list out (0,5,10,…,55).
Worked examples
30 5 * * 0,6converts to30 5 * * 0,6lossless0 9 * * MON-FRIconverts to0 9 * * MON-FRIlossless*/5 * * * *converts to*/5 * * * *losslessEvery converted expression above is produced by the same conversion engine the tool uses — generated and integrity-tested, not hand-written.
Lossy and refused conversions
No expression-level loss occurs in this direction — every workflow schedule expression is already valid Vixie cron. The migration risks are environmental. UTC-to-local drift is the big one: a 06:00 UTC nightly build becomes a 06:00-local job that runs at a different real-world moment on every differently-configured host. The others are gains, not losses — no more 60-day auto-disable, no queue-delay at busy minutes, and the OR-semantics of doubly-restricted day fields behave identically since both dialects share the POSIX field model.
FAQ
The expression converted unchanged — is there anything to actually do?
Check the timezone. Workflow schedules evaluated in UTC; your crontab runs in system-local time. Either set the host (or TZ/CRON_TZ) to UTC, or re-derive the hours for local time deliberately.
Will */5 work everywhere?
On Vixie-derived crons (Linux distributions, macOS) — yes. Strict POSIX cron has no step syntax, so the portable spelling is the full comma list: 0,5,10,15,20,25,30,35,40,45,50,55.