Refuse to publish a site built from a hollow index.
Health answering 200 and the index being complete are different claims. A year of ~31-event backfills left a perfectly healthy API serving a real, correct, complete list of eight mints. A build against that succeeds — it prerenders eight cards — and rsync --delete-after then replaces fifty-five with eight. cashumints-web.service gains a second ExecStartPre after the health wait: count /api/mints, and exit non-zero below MIN_MINTS_FOR_BUILD (default 20, overridable with `systemctl edit`). A refusal aborts the unit before `pnpm build`, and publishing is ExecStartPost, so the previously published site is untouched; the OnFailure alert added in the last commit says why. Counted by the "host": key rather than by counting braces, because the list payload is about to carry a nested object per mint. A curl that fails at all counts as zero, which is below every floor — so an API that fell over between the health check and this line refuses the build instead of sailing through it. Verified against three live APIs: 73 mints passes, a doctored 8-mint database fails with the reason, and a dead port fails. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
0ebc8ada54
commit
060c7f1a59
@@ -52,6 +52,40 @@ Environment=PUBLIC_API_URL=
|
||||
# rather than letting the first fetch die on ECONNREFUSED. /api/health answers 503 until
|
||||
# it is genuinely ready, and curl -f treats that as a failure, so the loop keeps waiting.
|
||||
ExecStartPre=/usr/bin/timeout 90 /bin/sh -c 'until curl -sf -o /dev/null http://127.0.0.1:8788/api/health; do sleep 1; done'
|
||||
|
||||
# Then: does the API actually have an index to build a site out of?
|
||||
#
|
||||
# Health answering 200 says the process is up and its last backfill read something. It
|
||||
# does not say how many mints are in the table, and those are different questions — the
|
||||
# year of ~31-event backfills had a healthy API serving a real, complete, correct list of
|
||||
# eight mints. A build against that succeeds, prerenders eight cards, and rsync happily
|
||||
# replaces fifty-five with eight.
|
||||
#
|
||||
# So count the list before spending twenty minutes building from it. Below the floor
|
||||
# this exits non-zero, systemd abandons the unit at ExecStartPre, and — because publishing
|
||||
# is ExecStartPost, after the build — the previously published site is never touched. The
|
||||
# site stays exactly as it was and the OnFailure alert says why.
|
||||
#
|
||||
# Counted by the `"host":` key, one per item, rather than by counting `{`: the list
|
||||
# payload carries a nested object per mint (its NUT capability switches), so brace
|
||||
# counting would report roughly double. No jq: it is not installed on this host and a
|
||||
# build gate should not add a dependency to run.
|
||||
#
|
||||
# `Q` is a double-quote character, built with printf rather than written literally,
|
||||
# because this whole command is already inside systemd's single quotes and a quote of
|
||||
# either kind in the grep pattern would end the argument early.
|
||||
#
|
||||
# A curl that fails for any reason leaves `n` empty, `$${n:-0}` reads that as zero, and
|
||||
# zero is below every floor — so an API that fell over between the health check above and
|
||||
# this line refuses the build rather than sailing through it.
|
||||
Environment=MIN_MINTS_FOR_BUILD=20
|
||||
ExecStartPre=/bin/sh -c 'Q=$$(printf "\\042"); \
|
||||
n=$$(curl -sf --max-time 30 http://127.0.0.1:8788/api/mints | grep -o "$${Q}host$${Q}:" | wc -l); \
|
||||
if [ "$${n:-0}" -lt "$$MIN_MINTS_FOR_BUILD" ]; then \
|
||||
printf "<3>%s\\n" "refusing to build: /api/mints returned $${n:-0} mints, floor is $$MIN_MINTS_FOR_BUILD. Previous site left untouched."; \
|
||||
exit 1; \
|
||||
fi; \
|
||||
printf "%s\\n" "build gate: $$n mints, floor $$MIN_MINTS_FOR_BUILD"'
|
||||
# Check `which pnpm` on the host: a corepack or pnpm-home install sits outside /usr/bin,
|
||||
# and systemd's PATH does not include it.
|
||||
ExecStart=/usr/bin/pnpm build
|
||||
|
||||
Reference in New Issue
Block a user