feat(ci): missed-run heartbeat for the daily sync cron - #72
Merged
Conversation
A failed sync run surfaces on its own, but a run that never fires is silent: GitHub can drop scheduled runs, auto-disable the workflow after inactivity, or lose the schedule. Add a separate scheduled workflow (heartbeat.yml) that checks the last successful scheduled sync-translation run and alerts when it is older than a threshold, so a silently missed run is caught. It does not depend on the sync workflow running, so it still fires once that workflow has stopped. The staleness decision lives in a pure heartbeat_run_is_stale() in lib.sh with bats coverage; HEARTBEAT_MAX_AGE_HOURS (30) carries margin above the 24h cadence. Alerting is interim (fails the job); point it at the shared notification channel once the failure-notification work lands.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughAdds a scheduled heartbeat workflow that checks the latest successful scheduled translation-sync run, uses shared timestamp validation, and fails with an error when the run exceeds the 30-hour threshold. Tests cover missing, stale, fresh, and boundary timestamps. ChangesTranslation sync heartbeat
Estimated code review effort: 3 (Moderate) | ~20 minutes Sequence Diagram(s)sequenceDiagram
participant HeartbeatWorkflow
participant GitHubActions
participant heartbeat_run_is_stale
HeartbeatWorkflow->>GitHubActions: query latest successful scheduled sync run
GitHubActions-->>HeartbeatWorkflow: return createdAt timestamp
HeartbeatWorkflow->>heartbeat_run_is_stale: compare timestamp with 30-hour threshold
heartbeat_run_is_stale-->>HeartbeatWorkflow: return stale or fresh status
HeartbeatWorkflow-->>GitHubActions: emit error and fail when stale
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
whisper67265
self-requested a review
July 30, 2026 14:34
whisper67265
requested changes
Jul 30, 2026
updatedAt moves when an old run is rerun, so a stopped schedule whose last run was manually rerun looked healthy. Query createdAt, the schedule-fire time, so the age reflects when the run actually fired.
whisper67265
approved these changes
Jul 30, 2026
wpak-ai
approved these changes
Jul 30, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #71
Problem
The daily translation sync (
.github/workflows/sync-translation.yml,cron: "0 0 * * *") surfaces a failed run on its own, but a run that never fires is silent: GitHub can drop scheduled runs, auto-disable the workflow after repo inactivity, or lose the schedule. A silently missed sync can go unnoticed until translations fall behind.What changed
.github/workflows/heartbeat.yml(0 12 * * *, offset from the sync's00:00) queries the last successful scheduledsync-translationrun via theghAPI and alerts when it is older than the threshold. It runs independently, so it still fires once the sync workflow has stopped.heartbeat_run_is_stale()inassets/lib.sh(missing or older-than-threshold), with four bats tests (no-run / older / within / boundary).HEARTBEAT_MAX_AGE_HOURS = 30inassets/env.shcarries margin above the 24h cadence, so a delayed run does not trip the alert while a fully missed day is caught by the next heartbeat.Alerting is interim: the job fails so the missed run surfaces to watchers. It is a one-step swap to the shared notification channel once the failure-notification work (#66) provides one.
Repo lint (shellcheck + actionlint + JSON-schema) is clean and the full bats suite passes locally (135).
Summary by CodeRabbit