Skip to content

Server Readiness Check #501 #550

Server Readiness Check #501

Server Readiness Check #501 #550

Workflow file for this run

# Workflow for validating container image builds
name: Validate Container Images
on:
pull_request:
types:
- opened
- synchronize
- reopened
- ready_for_review
paths:
- "src/**"
- ".dockerignore"
- "pyproject.toml"
- ".github/workflows/image_smoke.yml"
# Allows running this workflow manually
workflow_dispatch:
concurrency:
group: image-smoke-${{ github.ref }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
jobs:
# Build and test all container images with optimized caching
image-build-test:
if: github.event.pull_request.draft == false || github.event_name == 'workflow_dispatch'
runs-on: ubuntu-latest
permissions:
pull-requests: write
contents: read
strategy:
fail-fast: false
matrix:
build:
- name: aio
dockerfile: src/Dockerfile
smoke_env: "-e API_SERVER_KEY=test-key-for-ci"
- name: client
dockerfile: src/client/Dockerfile
smoke_env: "-e API_SERVER_KEY=test-key-for-ci -e API_SERVER_URL=http://localhost -e API_SERVER_PORT=8000"
- name: server
dockerfile: src/server/Dockerfile
smoke_env: "-e API_SERVER_KEY=test-key-for-ci"
name: Build & Test - ${{ matrix.build.name }}
steps:
- name: Checkout Code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4.0.0
# Per-image GHA cache scope. The BuildKit GHA cache index is mutable per
# scope, so concurrent matrix writers to a shared scope would race and the
# last manifest would win, orphaning the other images' image-specific
# layers. Keeping scopes distinct preserves each image's steady-state
# warm-cache hits. security_scan.yml uses the same `aio-image` scope to
# share layers with the aio build here.
- name: Build Container Image
uses: docker/build-push-action@bcafcacb16a39f128d818304e6c9c0c18556b85f # v7.1.0
with:
context: .
file: ${{ matrix.build.dockerfile }}
tags: ${{ matrix.build.name }}:${{ github.sha }}
load: true
push: false
cache-from: type=gha,scope=${{ matrix.build.name }}-image
cache-to: type=gha,mode=max,scope=${{ matrix.build.name }}-image,compression=zstd
- name: Smoke Test - ${{ matrix.build.name }} Container
run: |
NAME="test-${{ matrix.build.name }}"
echo "Testing ${{ matrix.build.name }} container startup..."
docker run -d --name "$NAME" \
${{ matrix.build.smoke_env }} \
${{ matrix.build.name }}:${{ github.sha }}
# Full 10s stabilization window — catches containers that start
# successfully and then crash shortly after. Checking earlier would
# let short-lived startup failures pass.
echo "Waiting 10s for container to stabilize..."
sleep 10
if docker ps --filter "name=$NAME" --filter "status=running" --format '{{.Names}}' | grep -qx "$NAME"; then
echo "✅ ${{ matrix.build.name }} container started and is still running"
docker stop "$NAME"
exit 0
fi
echo "❌ ${{ matrix.build.name }} container failed to start or crashed"
docker logs "$NAME" 2>&1 || true
exit 1
- name: Cleanup Test Container
if: always()
run: |
NAME="test-${{ matrix.build.name }}"
docker stop "$NAME" 2>/dev/null || true
docker rm "$NAME" 2>/dev/null || true
# Summary job
image-validation-summary:
name: Validation Summary
if: always() && (github.event.pull_request.draft == false || github.event_name == 'workflow_dispatch')
runs-on: ubuntu-latest
permissions: {}
needs: [image-build-test]
steps:
- name: Evaluate results
run: |
if [[ "${{ contains(needs.*.result, 'failure') }}" == "true" ]]; then
echo "❌ One or more image validations failed"
exit 1
fi
echo "✅ All container image validations passed"