feat: add healthchecks.io pings to run-stories.sh and run-profiles.sh

Start/finish pings wired through gdl-cron.sh via HC_URL, finish ping
carries the run's log as its body (visible in the dashboard, no SSH
needed to diagnose a failure). Exit code is the trailing URL segment
by convention, so the existing "stories: 0 to sync" -> exit 75 remap
already reaches the dashboard as a failure too.

Also fixes the actual bug that would have made this useless: the
routine chown-permission rsync warning (the archive share is never
owned by the ssh user) made gdl-sync.py return 1 on every clean run,
not just failing ones -- harmless when a human reads the log, but it
would have pinged every successful run as a failure. publish() now
only masks that one specific, verified-benign error shape; a real
transfer failure sharing the same exit code (23) still fails loudly.
6 new tests.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011qAds5qr7nZRq5R4yAuxUk
This commit is contained in:
2026-09-14 14:01:17 -04:00
co-authored by Claude Sonnet 5
parent 8275416b6e
commit 9b2c33766f
6 changed files with 114 additions and 1 deletions
+17
View File
@@ -15,6 +15,13 @@ set -eu
MODE="${1:?usage: gdl-cron.sh stories|profiles|full-sweep}"
# healthchecks.io (or compatible) ping URL, e.g. https://hc-ping.com/<uuid>.
# Set by the run-*.sh wrapper for whichever mode has a check configured;
# unset here means no ping, silently. A ping failure (network blip, check
# deleted) must never fail the sync itself -- hence `|| true` throughout, and
# a short timeout (-m) so a hung ping can't hang the run.
HC_URL="${HC_URL:-}"
GDL_HOME="${GDL_HOME:-$HOME/gdl}"
INDEX="${GDL_INDEX:-https://instaarchive.ergosteur.com}"
PUBLISH="${GDL_PUBLISH:-agentapi@10.20.28.200:/volume1/rslsync/sync/Instagram-archive/archives/}"
@@ -57,6 +64,8 @@ esac
mkdir -p "$GDL_HOME/logs"
[ -n "$HC_URL" ] && curl -fsS -m 10 --retry 3 -o /dev/null "$HC_URL/start" || true
# Staging is wiped every run ON PURPOSE. What we already hold is decided by the
# skip-archive (--download-archive), never by which files happen to be sitting
# in staging, so starting empty is correct -- and it keeps the publish rsync
@@ -104,6 +113,14 @@ fi
echo "=== exit $status at $(date -Is) ===" | tee -a "$LOG"
# The log becomes the ping body -- healthchecks.io keeps the last ping's body
# and shows it in the dashboard, so a failure is diagnosable without SSHing
# in. The trailing URL segment is the exit code by convention: 0 means
# success, anything else means fail (this is how the "0 skipped" -> 75
# remap above also reaches the dashboard as a failure, not a quiet success).
[ -n "$HC_URL" ] && curl -fsS -m 10 --retry 3 --data-binary "@$LOG" \
-o /dev/null "$HC_URL/$status" || true
# Keep the log directory from growing without bound.
ls -1t "$GDL_HOME/logs" | tail -n +30 | while read -r old; do
rm -f "$GDL_HOME/logs/$old"