Convert Unix cron (POSIX/Vixie) to GitHub Actions

Move crontab expressions into GitHub Actions workflow schedules: alias expansion, UTC evaluation, and the platform rules that change even when the expression doesn't.

About this conversion

Honesty first: this is the easy direction. GitHub Actions speaks a POSIX-style five-field dialect with Sunday = 0, so most crontab expressions move into a workflow's schedule: block byte-identical — no renumbering, no field-count change. The one syntactic conversion that does real work is aliases: @daily and friends aren't accepted in workflow files, so they expand to their field form. The traps in this direction are operational, not syntactic — and they're worth knowing before the first missed run.

What changes in this conversion

  • Most expressions pass through unchanged — same five fields, same Sunday = 0 numbering.
  • @-aliases are expanded (@daily → the midnight field form); workflow files don't accept them.
  • Schedules default to UTC — since March 2026 a timezone: field exists alongside cron in the schedule block, which beats hand-shifting hours across DST.
  • Platform contract: in public repos, scheduled workflows auto-disable after 60 days of repository inactivity; schedules on forks are disabled by default; runs queued at busy minutes (like minute 0) can be delayed — staggering to an odd minute helps.

Worked examples

Weekdays at 09:00 (unchanged — now UTC)Try it →
0 9 * * 1-5converts to0 9 * * 1-5lossless
Once a day (alias expanded for workflow files)Try it →
@dailyconverts to0 0 * * *lossless
Every 15 minutes (unchanged)Try it →
*/15 * * * *converts to*/15 * * * *lossless

Every converted expression above is produced by the same conversion engine the tool uses — generated and integrity-tested, not hand-written.

Lossy and refused conversions

Nothing in this direction converts lossily at the expression level — even a both-day-fields expression keeps its POSIX OR-semantics, since GitHub Actions evaluates the same field model. What changes is everything around the expression: a crontab entry that ran in your server's local time now fires in UTC (or the declared timezone: field), and a schedule that ran unconditionally now depends on repository activity and runner availability. Treat the conversion as trivial and the migration as not.

FAQ

Why does my workflow fire at the wrong hour?

GitHub Actions evaluates schedules in UTC by default. A crontab that ran at 09:00 server-local time needs either the timezone: field (added March 2026) or a hand-shifted hour — and hand-shifting breaks twice a year at DST changes.

My scheduled workflow silently stopped running. Why?

In public repositories, scheduled workflows are disabled automatically after 60 days without repository activity. Forks also start with schedules disabled. Neither is an expression problem — check the Actions tab.

Free cron syntax cheat sheet

© 2026 Abel Solutions LLC. All rights reserved. · More from Abel Solutions: RegexPro — test and debug regular expressions · NuGate — open-source dependency age gate for NuGet