From 3daa351d70df95a639a671b6b46ec9ae393b1232 Mon Sep 17 00:00:00 2001 From: Lucas Berger Date: Sat, 13 Jun 2026 08:43:16 -0400 Subject: [PATCH] fix(16): WR-02/WR-05 robust boot-smoke and active .dockerignore checks WR-02: capture docker run exit directly (not the piped head exit) so a chatty booting image can't SIGPIPE to 141 and false-PASS; require the FATAL guard marker in output as a positive assertion. WR-05: strip comment lines and use anchored fixed-string (grep -qF) matching so a commented-out rule can't satisfy the hygiene check and patterns aren't treated as regexes. --- .gitea/workflows/publish.yml | 33 ++++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/.gitea/workflows/publish.yml b/.gitea/workflows/publish.yml index 2bd244f..34fc80b 100644 --- a/.gitea/workflows/publish.yml +++ b/.gitea/workflows/publish.yml @@ -96,10 +96,14 @@ jobs: echo "FAIL: .dockerignore does not exist" exit 1 fi - # Assert every forbidden pattern is covered by .dockerignore - for pattern in ".env" "node_modules" "apps/api/scripts" ".git" ".planning" "apps/api/tests" "apps/pwa/e2e"; do - if ! grep -q "$pattern" .dockerignore; then - echo "FAIL: .dockerignore missing pattern: $pattern" + # Assert every forbidden pattern is an ACTIVE ignore rule (WR-05). + # Strip comment lines first, then fixed-string match so a commented-out + # "# .env was here" can't satisfy the check and "$pattern" is never + # treated as a regex (e.g. ".env" matching "denv"). + for pattern in ".env" "node_modules" "apps/api/scripts" ".git" \ + ".planning" "apps/api/tests" "apps/pwa/e2e"; do + if ! grep -v '^[[:space:]]*#' .dockerignore | grep -qF "$pattern"; then + echo "FAIL: .dockerignore missing active rule: $pattern" exit 1 fi done @@ -121,20 +125,27 @@ jobs: run: | set -euo pipefail IMAGE="${{ steps.tags.outputs.sha_tag }}" + # WR-02: capture docker's exit code DIRECTLY, not a pipeline exit. Piping + # through `head -20` would let a chatty-but-booting regressed image emit + # 20 lines, SIGPIPE docker (exit 141), and false-PASS. Capture all output + # to a variable, then print a bounded slice for the log. set +e - timeout 15 docker run --rm \ + OUT=$(timeout 15 docker run --rm \ --env NODE_ENV=production \ --env DEV_AUTH_BYPASS=true \ - "$IMAGE" \ - 2>&1 | head -20 + "$IMAGE" 2>&1) EXIT=$? set -e - if [ "$EXIT" -eq 0 ]; then - echo "FAIL: Production image started successfully with DEV_AUTH_BYPASS=true — guard not working" + echo "$OUT" | head -20 + # 0 (clean start) and 124 (timeout) both mean the guard did NOT refuse boot. + if [ "$EXIT" -eq 0 ] || [ "$EXIT" -eq 124 ]; then + echo "FAIL: Production image did not refuse DEV_AUTH_BYPASS=true (exit $EXIT)" exit 1 fi - if [ "$EXIT" -eq 124 ]; then - echo "FAIL: Production image did not exit within 15s — guard not firing" + # Belt-and-suspenders: require the FATAL guard marker, so a refusal for + # some UNRELATED reason cannot masquerade as the guard working. + if ! echo "$OUT" | grep -q "DEV_AUTH_BYPASS=true is set in a production environment"; then + echo "FAIL: image refused boot (exit $EXIT) but NOT via the expected D-08 guard" exit 1 fi echo "PASS: Production image refused to start with DEV_AUTH_BYPASS=true (exit $EXIT)"