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.
This commit is contained in:
@@ -96,10 +96,14 @@ jobs:
|
|||||||
echo "FAIL: .dockerignore does not exist"
|
echo "FAIL: .dockerignore does not exist"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
# Assert every forbidden pattern is covered by .dockerignore
|
# Assert every forbidden pattern is an ACTIVE ignore rule (WR-05).
|
||||||
for pattern in ".env" "node_modules" "apps/api/scripts" ".git" ".planning" "apps/api/tests" "apps/pwa/e2e"; do
|
# Strip comment lines first, then fixed-string match so a commented-out
|
||||||
if ! grep -q "$pattern" .dockerignore; then
|
# "# .env was here" can't satisfy the check and "$pattern" is never
|
||||||
echo "FAIL: .dockerignore missing pattern: $pattern"
|
# 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
|
exit 1
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
@@ -121,20 +125,27 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
IMAGE="${{ steps.tags.outputs.sha_tag }}"
|
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
|
set +e
|
||||||
timeout 15 docker run --rm \
|
OUT=$(timeout 15 docker run --rm \
|
||||||
--env NODE_ENV=production \
|
--env NODE_ENV=production \
|
||||||
--env DEV_AUTH_BYPASS=true \
|
--env DEV_AUTH_BYPASS=true \
|
||||||
"$IMAGE" \
|
"$IMAGE" 2>&1)
|
||||||
2>&1 | head -20
|
|
||||||
EXIT=$?
|
EXIT=$?
|
||||||
set -e
|
set -e
|
||||||
if [ "$EXIT" -eq 0 ]; then
|
echo "$OUT" | head -20
|
||||||
echo "FAIL: Production image started successfully with DEV_AUTH_BYPASS=true — guard not working"
|
# 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
|
exit 1
|
||||||
fi
|
fi
|
||||||
if [ "$EXIT" -eq 124 ]; then
|
# Belt-and-suspenders: require the FATAL guard marker, so a refusal for
|
||||||
echo "FAIL: Production image did not exit within 15s — guard not firing"
|
# 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
|
exit 1
|
||||||
fi
|
fi
|
||||||
echo "PASS: Production image refused to start with DEV_AUTH_BYPASS=true (exit $EXIT)"
|
echo "PASS: Production image refused to start with DEV_AUTH_BYPASS=true (exit $EXIT)"
|
||||||
|
|||||||
Reference in New Issue
Block a user