From f91d4559f3eac8dc11e02f3af3f57157fe4e43ad Mon Sep 17 00:00:00 2001 From: Logan Cusano Date: Sun, 20 Sep 2026 20:36:17 -0400 Subject: [PATCH] deploy: treat an empty .last_good_tag the same as a missing one (#156) cat file 2>/dev/null || echo latest only falls back when cat itself fails (nonzero exit, i.e. the file is missing) -- a file that EXISTS but is EMPTY makes cat succeed with empty output, so PREV_TAG became "" instead of "latest". That "" failed the emptiness check further down and exited 1 -- AFTER git pull + docker compose up -d had already succeeded. Worse: exiting there skips the Health check step (Gitea Actions doesn't run later steps after a failure), and Health check is the ONLY step that ever writes a real value to .last_good_tag. Self-perpetuating: once the file went empty, every future deploy failed the same way forever, with the app itself deploying fine underneath it every time (confirmed against run 611: deploy log shows all three images pulled/recreated/started at 66bbf5b, and /health self-reports that exact GIT_SHA, baked into the image at build time -- two independent signals, same commit). ${VAR:-default} covers empty and unset in one expansion, matching the fallback behavior the surrounding comment already documented as intended. Co-Authored-By: Claude Sonnet 5 --- .gitea/workflows/deploy.yml | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/.gitea/workflows/deploy.yml b/.gitea/workflows/deploy.yml index 7cf5dd4..b865299 100644 --- a/.gitea/workflows/deploy.yml +++ b/.gitea/workflows/deploy.yml @@ -133,7 +133,20 @@ jobs: # has confirmed the tag it names actually answered /health. A # fresh VM with no file yet falls back to :latest, same escape # hatch as a manual `up -d` with no TAG set. - PREV_TAG=$(cat /opt/drb/.last_good_tag 2>/dev/null || echo latest) + # + # server-26#156: `cat missing-file || echo latest` only falls back + # when cat itself fails (nonzero exit) -- a file that EXISTS but is + # EMPTY (the state this file was found in, 2026-09-20) makes cat + # succeed with empty output, so PREV_TAG became "" instead of + # "latest". That "" then failed the emptiness check below and + # exited 1 -- AFTER git pull + up -d had already succeeded -- which + # skips the Health check step entirely (later steps don't run after + # a failure), and Health check is the ONLY thing that ever writes a + # real value here. Self-perpetuating: every deploy failed the same + # way forever, with the app itself deploying fine underneath it. + # ${VAR:-default} covers empty AND unset in one expansion. + PREV_TAG=$(cat /opt/drb/.last_good_tag 2>/dev/null) + PREV_TAG="${PREV_TAG:-latest}" echo "PREV_TAG=$PREV_TAG" # Deploy THIS commit's images, not :latest. Overlapping runs are