Cron Notes

2 min read

Parse, convert, and reconstruct cron schedule expressions. Handles five-field expressions and @-macros (@hourly, @daily, @weekly, @monthly, @yearly).

The three conversion notes

NoteInputOutputUse in
cronToMapstringmap (via sentinel)conversion path spec — produces nested object
cronFromMapmap onlystring — errors on stringonReconcile behind typeOf: map gate
cronFromAnymap or stringstringnormalize, status, conversion — unknown shape
# v1 (cron string) → v2 (structured map)
- from: v1
  to: v2
  spec:
    schedule: "{{ cronToMap .spec.schedule }}"

# v2 → v1: input may be map or legacy flat string
- from: v2
  to: v1
  spec:
    schedule: "{{ cronFromAny .spec.schedule }}"

# normalize block: collapse either shape to canonical string
normalize:
  spec:
    schedule: "{{ cronFromAny .spec.schedule }}"

# onReconcile Path B — input guaranteed a map by the when: gate
- name: "{{ .metadata.name }}"
  schedule: "{{ cronFromMap .spec.schedule }}"
  when:
    - field: spec.schedule
      operator: typeOf
      value: map

Validation and normalization

NoteSignatureReturns
cronValidstringbool — structurally valid (five fields present)
cronNormalizestringstring — expanded macros, exactly five fields
cronDescribestringstring — human-readable (“Every 5 minutes”)
- field: spec.schedule
  value: "{{ cronValid .spec.schedule }}"
  message: "spec.schedule must be a valid cron expression"
  action: deny

- path: scheduleDescription
  value: "{{ cronDescribe .spec.schedule }}"

Field extraction

NoteSignatureReturns
cronMinutestringminute field
cronHourstringhour field
cronDomstringday-of-month field
cronMonthstringmonth field
cronDowstringday-of-week field
cronFieldstring, intfield at position 0–4
cronExprmin hr dom mon dow stringcanonical five-field string
# Extract a single field
- path: scheduleMinute
  value: "{{ cronMinute .spec.schedule }}"

# Build from five explicit parts
schedule: "{{ cronExpr .spec.schedule.minute .spec.schedule.hour .spec.schedule.dayOfMonth .spec.schedule.month .spec.schedule.dayOfWeek }}"

Supported @-macros

MacroExpands toMeaning
@yearly / @annually0 0 1 1 *Once a year, Jan 1 at midnight
@monthly0 0 1 * *Once a month, 1st at midnight
@weekly0 0 * * 0Once a week, Sunday at midnight
@daily / @midnight0 0 * * *Once a day at midnight
@hourly0 * * * *Once an hour at minute 0

See also: pkg/note/docs/05-cron.md, conversion sentinel.