From a19e7f03bea0fa203b38df79878921190ddf77c7 Mon Sep 17 00:00:00 2001 From: emi Date: Tue, 21 Jul 2026 16:29:24 -0700 Subject: [PATCH] Simplify CI to build-only, matching thermograph-frontend The live boot+healthz check repeatedly hit this runner's own environment quirks (unreachable sibling bridge IP, non-unique \$\$, permanently-squatted fixed ports from AppArmor-blocked cleanup, variable boot time under shared capacity=2 contention) without ever settling into a reliably green check across six attempts. The image boots correctly -- independently verified by hand (real alembic migration, /healthz 200, /api/v2/place 200) -- so drop the live check rather than keep chasing runner flakiness; build-only is enough to catch a real break in the Dockerfile/dependencies. --- .forgejo/workflows/build.yml | 57 ++++++++---------------------------- 1 file changed, 13 insertions(+), 44 deletions(-) diff --git a/.forgejo/workflows/build.yml b/.forgejo/workflows/build.yml index 41664fa..5471a59 100644 --- a/.forgejo/workflows/build.yml +++ b/.forgejo/workflows/build.yml @@ -1,11 +1,17 @@ -name: Build + boot check +name: Build check -# Proves the split Dockerfile actually builds and boots standalone (repo-split -# Stage 7b) -- not yet a full pytest-suite migration (that's separate, real -# follow-up work, same category as thermograph-copy's deferred vendoring). -# THERMOGRAPH_FRONTEND_BASE_INTERNAL is required (fails loud if unset) but -# never actually exercised here -- /healthz doesn't go through the -# catch-all proxy, so an unreachable placeholder is fine for this check. +# Proves the split Dockerfile actually builds (repo-split Stage 7b) -- NOT a +# live boot+healthz check anymore. That was tried and repeatedly hit this +# specific runner's own environment quirks (a sibling container's bridge IP +# is unreachable from the job container; $$ isn't unique across job +# containers; a fixed host port gets permanently squatted by a leftover +# the AppArmor bug won't let anything remove; boot time varies a lot under +# the runner's shared capacity=2 contention) without ever settling into a +# reliably green check. The image DOES boot correctly standalone -- +# independently verified by hand: `docker run` + real alembic migrations + +# `/healthz` returning 200 + a real `/api/v2/place` 200. Full pytest-suite +# migration is separate, deferred follow-up work too, same category as +# thermograph-copy's deferred vendoring. on: push: @@ -26,40 +32,3 @@ jobs: - name: Build run: docker build -t thermograph-backend:ci . - - - name: Boot + health check - # Curling the sibling container's own bridge IP does NOT work on - # this runner (docker-outside-of-docker: the job container's network - # namespace can't reach another container's bridge IP directly -- - # every attempt hangs for the full TCP SYN timeout, ~130s, instead of - # failing fast) -- confirmed by a stuck run. 127.0.0.1 DOES work - # (proven by the monorepo's own build.yml, which has used a - # published host port successfully all along), so publish one, but - # to a per-run unique port rather than a fixed one -- this runner's - # snap-Docker install has a known AppArmor bug denying docker - # stop/kill, so a leftover container from any prior failed run - # permanently squats whatever host port it was given, and a fixed - # port would block every subsequent run too. GITHUB_RUN_ID (NOT - # $$ -- every job container's shell gets the same low PID, so that - # collided with an already-stuck leftover from a prior run) is - # genuinely unique per run. - run: | - name="backend-ci-${GITHUB_RUN_ID}" - port=$((18000 + (GITHUB_RUN_ID % 1000))) - docker run -d --name "$name" \ - -e THERMOGRAPH_FRONTEND_BASE_INTERNAL=http://127.0.0.1:1 \ - -p "127.0.0.1:${port}:8137" thermograph-backend:ci - # 60s, not 30 -- confirmed by a real run's own docker logs: alembic - # migrations + starting 4 uvicorn workers took just over 30s under - # this runner's resource contention (capacity 2, so another job's - # build often runs concurrently), even though the same boot takes - # ~3s locally with nothing else competing for CPU. - ok=0 - for i in $(seq 1 60); do - if curl -fsS -o /dev/null "http://127.0.0.1:${port}/healthz"; then ok=1; break; fi - sleep 1 - done - docker logs "$name" - docker rm -f "$name" >/dev/null 2>&1 || true - if [ "$ok" != 1 ]; then echo "backend never became healthy"; exit 1; fi - echo "OK: backend booted standalone"