GitHub Actions cron is fixed. Sometimes you don't want that — scraping, rate limits, or just not stacking with everyone else on the hour.
Here's a small bash trick: each run picks a new minute and commits it back into the workflow file.
Setting up the randomized workflow
Create randomize-workflow.sh. It generates a random minute and updates the workflow's cron line.
#!/bin/bash
workflow_file=".github/workflows/example.yml"
minute=$(shuf -i 0-58 -n 1)
cron_string="$minute * * * *"
# Use sed to find and replace the cron line in the workflow file
sed -i "s/^ - cron:.*/ - cron: $cron_string/" "$workflow_file"The script points at the workflow file, picks a minute between 0 and 58 with shuf, builds a cron string, and uses sed to swap the line.
In example.yml, say you have a job that currently runs every hour at minute 1. This script replaces that fixed schedule on each run.
Before using it, add a repo secret named COMMIT_TOKEN with read/write access to the repo. The workflow needs it to commit and push the updated cron.
Modifying the GitHub workflow
Wire the script and token into the workflow:
name: Example Random Workflow
on:
push:
branches: [main]
workflow_dispatch:
schedule:
- cron: 1 * * * *
jobs:
download:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
with:
fetch-depth: 0
token: ${{ secrets.COMMIT_TOKEN }}
- name: Randomize time for next run
run: |
chmod +x ./randomize-workflow.sh
./randomize-workflow.sh
- name: Commit & push changes
run: |
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git config user.name "github-actions[bot]"
git add .github/workflows/example.yml
git commit -m "Randomized GitHub Actions workflow [skip ci]"
git pull --rebase
git pushThe "Randomize time for next run" step runs the script, which rewrites the cron for next time.
Useful when you care more about not being predictable than about firing at :00. Monitoring gets slightly harder; trade off accordingly. You'll need a COMMIT_TOKEN that can push to the repo.