From 06fd7c7dc8e25ffed3752060977567f609d017a0 Mon Sep 17 00:00:00 2001 From: Nick M Date: Mon, 13 Jul 2026 02:12:30 -0500 Subject: [PATCH] docs(miner): add unattended scheduling & failure-alerting guidance Operational guidance (#4840) for running the miner's two scheduled commands (`manage poll`, `discover`) unattended: the shared exit-code contract (0 success / 2 failure) that alerting keys on, the `--no-update-check` / `--json` flags for scheduled runs, worked cron and systemd service+timer examples, and three failure-alerting patterns (cron MAILTO/logger, systemd OnFailure=, and a wrapper script). Closes #4840 --- .../docs/unattended-scheduling.md | 98 +++++++++++++++++++ 1 file changed, 98 insertions(+) create mode 100644 packages/gittensory-miner/docs/unattended-scheduling.md diff --git a/packages/gittensory-miner/docs/unattended-scheduling.md b/packages/gittensory-miner/docs/unattended-scheduling.md new file mode 100644 index 0000000000..20eca96e66 --- /dev/null +++ b/packages/gittensory-miner/docs/unattended-scheduling.md @@ -0,0 +1,98 @@ +# gittensory-miner — unattended scheduling & failure alerting + +Operational guidance for running the miner's scheduled commands — `manage poll` and `discover` — +unattended on a timer (cron or systemd), and for alerting when a run fails. These are the two commands +most likely to run on a schedule; everything they need is local and they make no interactive prompts. + +> **Scope:** scheduling + failure alerting for `manage poll` / `discover`. For local-state recovery see +> [`operations-runbook.md`](operations-runbook.md); for deployment layout see +> [`../DEPLOYMENT.md`](../DEPLOYMENT.md). + +## The exit-code contract (what to alert on) + +Both commands follow the same convention, so any scheduler can detect a failed run from the exit code: + +| Exit code | Meaning | +| --- | --- | +| `0` | Success — the command completed. | +| `2` | Failure — invalid arguments, or the run hit an error (network / API / local state). **Alert on this.** | + +For scheduled runs, two flags matter: + +- `--no-update-check` (or `GITTENSORY_MINER_NO_UPDATE_CHECK=1`) — skip the npm-registry version nudge so + an unattended run never depends on / prints it. +- `--json` — machine-parseable stdout, so an alert handler can attach the structured output. + +## cron + +```cron +# crontab env applies to every job below. +MAILTO=you@example.com +GITTENSORY_MINER_NO_UPDATE_CHECK=1 + +# Poll a tracked PR every 10 minutes. cron mails the output to MAILTO on any non-zero exit; the +# `|| logger` fallback also records the failure (with the command's exit code) to syslog for alerting. +*/10 * * * * /usr/local/bin/gittensory-miner manage poll acme/widgets 42 --json || logger -t gittensory-miner "manage poll failed (exit $?)" + +# Discover + enqueue candidate work hourly. +0 * * * * /usr/local/bin/gittensory-miner discover --search "label:good-first-issue" --json || logger -t gittensory-miner "discover failed (exit $?)" +``` + +In `cmd || logger "... $?"`, `$?` on the right of `||` is the exit code of `cmd` (the `||` branch runs +immediately after `cmd` fails), so it logs the real failing code. + +## systemd (service + timer) + +A `oneshot` service plus a timer is the more observable option: `systemctl status` / `journalctl` +capture each run, and `OnFailure=` is a first-class alerting hook. + +`gittensory-miner-discover.service`: +```ini +[Unit] +Description=gittensory-miner discover +OnFailure=gittensory-miner-alert@%n.service + +[Service] +Type=oneshot +Environment=GITTENSORY_MINER_NO_UPDATE_CHECK=1 +# A non-zero exit (2) marks the unit failed and triggers OnFailure=. +ExecStart=/usr/local/bin/gittensory-miner discover --search "label:good-first-issue" --json +``` + +`gittensory-miner-discover.timer`: +```ini +[Unit] +Description=Run gittensory-miner discover hourly + +[Timer] +OnCalendar=hourly +Persistent=true + +[Install] +WantedBy=timers.target +``` + +Enable with `systemctl enable --now gittensory-miner-discover.timer`. + +## Alerting on failure + +Every option keys on the same exit-code contract (`2` = failure): + +- **cron:** set `MAILTO`, and/or append `|| ` — the examples use `logger`; substitute a + webhook `curl`, a PagerDuty/Slack CLI, etc. +- **systemd:** `OnFailure=gittensory-miner-alert@%n.service` runs a templated alert unit on any non-zero + exit. A minimal alert unit: + ```ini + # gittensory-miner-alert@.service + [Service] + Type=oneshot + ExecStart=/usr/local/bin/notify-failure "gittensory-miner unit %i failed" + ``` +- **wrapper script:** for any scheduler, wrap the command and branch on `$?`: + ```sh + #!/bin/sh + gittensory-miner "$@" || { notify-failure "gittensory-miner $* exited $?"; exit 1; } + ``` + +Keep `--json` on scheduled runs so the alert handler can forward the structured output; the +human-readable form is for interactive use.