The test image swaps in Caddyfile.test, so the production Caddyfile was never exercised by CI: the parse error from issue #20 sailed through every check and only surfaced when the deploy gate failed — after the broken container had already replaced the healthy one. Running `caddy validate` (same caddy:2-alpine base as the Dockerfile) on both files up front fails the PR check in seconds instead. Touches the frozen .github/workflows/ per explicit product-owner approval in #26. Closes #26 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
61 lines
2.1 KiB
YAML
61 lines
2.1 KiB
YAML
name: Test
|
|
|
|
on:
|
|
workflow_call:
|
|
|
|
jobs:
|
|
build-and-test:
|
|
runs-on: ubuntu-latest
|
|
|
|
steps:
|
|
- name: Checkout
|
|
uses: actions/checkout@v4
|
|
|
|
# The test image below swaps in Caddyfile.test, so the production
|
|
# Caddyfile is otherwise never exercised by CI — an invalid config then
|
|
# only surfaces when the deploy health-gate fails, after the broken
|
|
# container already replaced the healthy one (issue #20/#26). Validate
|
|
# both files up front so a parse error fails the PR check in seconds.
|
|
- name: Validate Caddyfiles
|
|
run: |
|
|
docker run --rm -v "$PWD":/workspace -w /workspace caddy:2-alpine \
|
|
caddy validate --config Caddyfile --adapter caddyfile
|
|
docker run --rm -v "$PWD":/workspace -w /workspace caddy:2-alpine \
|
|
caddy validate --config Caddyfile.test --adapter caddyfile
|
|
|
|
- name: Build Docker image
|
|
run: docker build -t learning-platform .
|
|
|
|
- name: Build test image
|
|
run: |
|
|
cat > Dockerfile.test <<'EOF'
|
|
FROM learning-platform
|
|
COPY Caddyfile.test /etc/caddy/Caddyfile
|
|
EOF
|
|
docker build -t learning-platform-test -f Dockerfile.test .
|
|
|
|
- name: Start container
|
|
run: |
|
|
docker run -d --network gitea --name test-container learning-platform-test
|
|
sleep 5
|
|
|
|
- name: Test homepage
|
|
run: |
|
|
status=$(curl -s -o /dev/null -w "%{http_code}" http://test-container)
|
|
if [ "$status" != "200" ]; then
|
|
echo "Homepage failed with status $status"
|
|
exit 1
|
|
fi
|
|
echo "✓ Homepage OK"
|
|
|
|
- name: Test security headers
|
|
run: |
|
|
headers=$(curl -sI http://test-container)
|
|
echo "$headers" | grep -q "X-Frame-Options" || (echo "Missing X-Frame-Options" && exit 1)
|
|
echo "$headers" | grep -q "X-Content-Type-Options" || (echo "Missing X-Content-Type-Options" && exit 1)
|
|
echo "✓ Security headers OK"
|
|
|
|
- name: Cleanup
|
|
if: always()
|
|
run: docker stop test-container && docker rm test-container
|