rollcron is a self-updating cron scheduler that pulls job definitions from a git repository and executes them according to their schedules.
┌─────────────────────────────────────────────────────────────┐
│ rollcron │
├─────────────────────────────────────────────────────────────┤
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────┐ │
│ │ Pull Task │───▶│ Config │───▶│ Scheduler │ │
│ │ (interval) │ │ Parser │ │ (per-second) │ │
│ └─────────────┘ └─────────────┘ └─────────────────┘ │
│ │ │ │
│ ▼ ▼ │
│ ┌─────────────┐ ┌─────────────────┐ │
│ │ git pull │ │ Job Executor │ │
│ │ + archive │ │ (with timeout) │ │
│ └─────────────┘ └─────────────────┘ │
└─────────────────────────────────────────────────────────────┘
~/.cache/rollcron/
├── <repo>-<hash>/ # Source of Truth (SoT)
│ ├── .git/
│ └── rollcron.yaml
├── <repo>-<hash>@<job-id>/ # Job working directory (by ID)
│ └── (git archive snapshot, no .git)
└── <repo>-<hash>@<job-id-2>/
└── (git archive snapshot, no .git)
File: rollcron.yaml
jobs:
<job-id>: # Required: unique job identifier (key)
name: <string> # Optional: display name (defaults to job-id)
schedule:
cron: "<cron-expr>" # Required: 5-field cron expression
run: <string> # Required: shell command to execute
timeout: <duration> # Optional: default "10s"
concurrency: <strategy> # Optional: default "skip"| Strategy | Behavior |
|---|---|
parallel |
Allow concurrent runs |
wait |
Wait for previous run to complete |
skip |
Skip if previous run still active (default) |
replace |
Kill previous run, start new |
jobs:
build:
name: "Build Project"
schedule:
cron: "0 * * * *"
run: cargo build --release
timeout: 5m
concurrency: wait
health-check:
schedule:
cron: "*/5 * * * *"
run: curl -f http://localhost/health
concurrency: skipStandard 5-field format: minute hour day-of-month month day-of-week
Examples:
*/5 * * * *- every 5 minutes0 * * * *- every hour0 2 * * *- daily at 2:00 AM0 0 * * 0- weekly on Sunday
<n>s- seconds (e.g.,30s)<n>m- minutes (e.g.,5m)<n>h- hours (e.g.,1h)
- Wait for pull interval
- Execute
git pull --ff-onlyon SoT - Parse
rollcron.yaml - For each job:
git archive HEAD | tar -xto job directory (by job ID) - Notify scheduler of config update
- Scheduler checks every second
- If job schedule matches current time (within 1s window):
- Spawn async task
- Execute command in job's working directory
- Apply timeout
- Log result with display name
- Jobs run in isolated directories (snapshots)
- Pull/sync happens independently of job execution
- Jobs can run during pull without interference
- Config reload triggers scheduler restart
rollcron [OPTIONS] <REPO>
Arguments:
<REPO> Path to local repo or remote URL (required)
Options:
--pull-interval <SECONDS> Pull interval [default: 3600]
-h, --help Print help
| Error | Behavior |
|---|---|
| git pull fails | Log error, retry next interval |
| Config parse fails | Log error, keep previous config |
| Job sync fails | Log error, skip config reload |
| Job timeout | Kill job, log timeout error |
| Job command fails | Log stderr, continue scheduler |
git- for clone, pull, archive operationstar- for extracting archivessh- for executing job commands