This article was last updated on January 12, 2025, to include advanced techniques for configuring cron schedules in GitHub Actions, such as handling timezone conversions, scheduling workflows with multiple conditions, and debugging inactive or misconfigured schedules, along with simplified explanations to enhance clarity.
What is GitHub Actions cron?
GitHub Actions cron is the feature that allows you to schedule the execution of workflows automatically whenever they reach a certain time. In other words, this is much like setting up bill payments: you set this once, and then it will routinely run on time without your needing to interfere. You define the schedule using cron syntax, for instance, '30 5 * * *' - runs every day at 5:30 AM UTC.
After years of automating the CICD pipeline, I must confidently say scheduled workflows are amongst those powerful and, at the same time, very misunderstood GitHub Actions features. I recall once trying to do a nightly build-the first time was hours into debugging as to why my workflow was not running on schedule. Spoiler alert-just forgot about conversion to UTC.
Steps we will cover in this article:
- How to Use Cron Syntax in GitHub Actions
- GitHub Actions Cron Schedule Builder
- Basic GitHub Actions Schedule Examples
- Common GitHub Actions Schedule Problems
- GitHub Actions Schedule Best Practices
- How to Debug GitHub Actions Schedules
- Cron Syntax Field Values
- Conclusion
How to Use Cron Syntax in GitHub Actionsโ
Cron syntax: Think of it in terms of trying to set the alarm clock radio. Just like your alarm must have time to awaken, cron requires the additional five to let it know just at which time:
Here is how I break it down:
# Format: minute hour day_of_month month day_of_week
'30 5 * * *' # Runs at 5:30 AM UTC every day
It's like saying: "Wake me up at 5:30 AM every day" - the asterisks mean "every" for that position.
GitHub Actions Cron Schedule Builderโ
I've put together the following interactive tool to help you visualize and craft cron schedules. Simply select the schedule you wish to implement, and it will generate the appropriate syntax in cron:
Cron Schedule Builder
0 0 * * *
Runs every day at 12:00 AM UTC
Basic GitHub Actions Schedule Examplesโ
Let me share some basic examples I use daily. These are perfect for getting started with scheduled workflows:
How to Run Daily Code Cleanup?โ
It basically helps you keep your repo clean by automatically removing those pesky temporary files and old logs that pile up.
name: Daily Code Cleanup
on:
schedule:
- cron: '0 0 * * *' # Every day at midnight UTC
jobs:
cleanup:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Remove old files
run: |
find . -type f -name "*.tmp" -mtime +7 -delete
find . -type f -name "*.log" -mtime +7 -delete
How to Schedule Weekly Dependency Updates?โ
You know how annoying it is to manually check for outdated packages, right? This workflow does all that heavy lifting for you every Monday morning. It'll check your dependencies and let you know if anything needs updating.
name: Weekly Dependency Check
on:
schedule:
- cron: '0 9 * * 1' # Every Monday at 9 AM UTC
jobs:
update:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Check for updates
run: |
npm outdated
npm audit
How to Generate Monthly Reports Automatically?โ
This is a real time-saver! Instead of scrambling at the end of each month to put together reports, this workflow automatically generates them and even emails them out.
name: Monthly Report
on:
schedule:
- cron: '0 0 1 * *' # First day of every month
jobs:
report:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Generate report
run: |
echo "Generating monthly report..."
./scripts/generate-report.sh
- name: Send email
uses: dawidd6/action-send-mail@v3
with:
server_address: smtp.gmail.com
server_port: 465
username: ${{ secrets.EMAIL_USERNAME }}
password: ${{ secrets.EMAIL_PASSWORD }}
subject: Monthly Report
body: Monthly report attached
attachments: ./report.pdf
How to Set Up Hourly Health Checks?โ
This one's like having a watchdog for your services. It pings your endpoints every 30 minutes to make sure everything's running smoothly. If something's wrong, it'll let you know right away instead of waiting for angry customer emails.
name: Service Health Check
on:
schedule:
- cron: '*/30 * * * *' # Every 30 minutes
jobs:
health_check:
runs-on: ubuntu-latest
steps:
- name: Check service health
run: |
response=$(curl -s -o /dev/null -w "%{http_code}" https://api.example.com/health)
if [ $response -ne 200 ]; then
echo "Service is down!"
1
fi
Common GitHub Actions Schedule Problemsโ
I have worked with GitHub Actions a lot and have seen many teams face common problems with cron scheduling. Here are the main issues that can cause problems with your workflows:
Timezone Confusionโ
# โ Wrong: Thinking 9 AM local time
- cron: '0 9 * * *' # Actually runs at 9 AM UTC!
# โ
Right: Calculate UTC offset
- cron: '0 14 * * *' # Runs at 9 AM EST (UTC-5)
Invalid Schedulesโ
# โ Wrong: Invalid day of month
- cron: '0 0 31 2 *' # February 31st doesn't exist!
# โ
Right: Use last day of month
- cron: '0 0 28-31 * *' # Runs on the last day of every month
GitHub Actions Schedule Best Practicesโ
Having broken production a few times, here's my golden rules:
Stagger Your Schedulesโ
Look, you don't want all your workflows hitting GitHub's servers at the same time - that's just asking for trouble! Instead, spread them out a bit. For example, if you have multiple daily jobs, run one at 1 AM, another at 1:15 AM, and so on. This helps prevent resource bottlenecks and makes your workflows more reliable. Plus, it makes debugging way easier since you're not trying to figure out which workflow caused an issue when they all ran at exactly the same time.
# Example of staggered schedules
name: Staggered Workflows
on:
schedule:
- cron: '0 1 * * *' # First job at 1 AM UTC
- cron: '15 1 * * *' # Second job at 1:15 AM UTC
- cron: '30 1 * * *' # Third job at 1:30 AM UTC
Multiple Schedulesโ
Sometimes you need different schedules for different days - like running tests more frequently during work hours and less on weekends. GitHub Actions lets you set multiple cron schedules in the same workflow. It's super flexible! You can have one schedule for weekdays, another for weekends, or even different times for different regions.
on:
schedule:
- cron: '0 2 * * 1-5' # Weekdays at 2 AM
- cron: '0 4 * * 0,6' # Weekends at 4 AM
How to Debug GitHub Actions Schedulesโ
And when things go wrong-and believe me, they do-here is my debugging checklist:
Check for Repository Activityโ
Github automatically disables the workflow after a period of inactivity over 60 days
- Solution: Do a minor commit or manually trigger the workflow
Check Permissionsโ
Sometimes your workflow might fail because of permission issues - it's more common than you'd think! Make sure you've got the right permissions set up. Here's a basic example where we explicitly set read permissions for the job. You might need different permissions based on what your workflow is doing (like write access for pushing changes).
jobs:
scheduled-job:
permissions:
contents: read # Explicitly set permissions
Cron Syntax Field Valuesโ
Field | Values | Description |
---|---|---|
Minute | 0-59 | Specifies the minute when the workflow runs. |
Hour | 0-23 | Specifies the hour when the workflow runs. |
Day of Month | 1-31 | Specifies the day of the month for the workflow. |
Month | 1-12 | Specifies the month when the workflow runs. |
Day of Week | 0-7 (0 and 7 = Sunday) | Specifies the day of the week for the workflow. |
Conclusionโ
Scheduled workflows that work for you in GitHub Actions are like having this 'assistant' that works 24/7. Once you understand the cron syntax and avoid some common pitfalls, they become one of the most valuable resources in automating tasks.
Remember: start small, test extensively, and always be timezone-aware. And if you need help to monitor your schedules, check out some tools like CICube that can give you a helping hand in keeping your GitHub Actions resources in check.