From c60bfb2b89aeb81062d710d28ee2af7d0ba49d29 Mon Sep 17 00:00:00 2001 From: Grant Whitmer Date: Thu, 13 Aug 2026 23:27:38 -0400 Subject: [PATCH] I-12: fail the build when COMMIT_SHA is empty MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit /version went null after a deploy — the exact "service cannot name its own commit" defect this project was built to prevent, caught by its own honesty check. Cause: the sed replaced "" with "" (a no-op when COMMIT_SHA is empty) and the grep then matched that same empty string, so the guard verified nothing. A build with no COMMIT_SHA passed and shipped a container reporting commit_sha: null. Now the build fails loudly instead. Second cause of the stale deploy, and it was mine: an earlier `git commit --amend` + force-push rewrote history the Veron deploy checkout was already sitting on, leaving it divergent so `git pull -q` failed SILENTLY (-q hid "Need to specify how to reconcile divergent branches"). Two lessons: do not force-push a branch a deploy checkout tracks, and do not pull with -q in a deploy script. Co-Authored-By: Claude (Fable 5) --- Dockerfile | 9 ++++++++- api/tests/test_invariants.py | 9 +++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 35148a5..93e8c79 100644 --- a/Dockerfile +++ b/Dockerfile @@ -18,7 +18,14 @@ COPY alembic ./alembic COPY alembic.ini ./ COPY scripts ./scripts -RUN sed -i "s|^BAKED_COMMIT_SHA: str = \"\"|BAKED_COMMIT_SHA: str = \"${COMMIT_SHA}\"|" api/app/buildinfo.py \ +# I-12: an EMPTY COMMIT_SHA must fail the build, not sail through it. +# Previously the sed replaced "" with "" (a no-op) and the grep then matched +# that same empty string, so a build with no COMMIT_SHA passed and shipped a +# container reporting commit_sha: null — exactly the "service cannot name its +# own commit" defect this project exists to prevent. Caught 2026-08-14 when +# /version went null after a deploy. +RUN test -n "${COMMIT_SHA}" || (echo "FATAL: COMMIT_SHA build arg is empty (I-12)" && false) \ + && sed -i "s|^BAKED_COMMIT_SHA: str = \"\"|BAKED_COMMIT_SHA: str = \"${COMMIT_SHA}\"|" api/app/buildinfo.py \ && sed -i "s|^BAKED_BUILT_AT: str = \"\"|BAKED_BUILT_AT: str = \"${BUILT_AT}\"|" api/app/buildinfo.py \ && grep -q "BAKED_COMMIT_SHA: str = \"${COMMIT_SHA}\"" api/app/buildinfo.py diff --git a/api/tests/test_invariants.py b/api/tests/test_invariants.py index 984008a..ab1f6b5 100644 --- a/api/tests/test_invariants.py +++ b/api/tests/test_invariants.py @@ -694,3 +694,12 @@ async def test_security_no_bearer_is_still_401(): with _pytest.raises(RepairPointer) as exc: await get_caller(req, authorization=None, x_service_token=None) assert exc.value.status_code == 401 + + +def test_i12_build_fails_when_commit_sha_is_empty(): + """The sed+grep pair silently accepted an empty COMMIT_SHA: it replaced "" + with "" and then matched that same empty string, shipping a container that + reported commit_sha: null. That is the exact defect I-12 exists to prevent, + and it happened on 2026-08-14.""" + df = (ROOT / "Dockerfile").read_text() + assert 'test -n "${COMMIT_SHA}"' in df