Server Readiness Check #501 #550
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # 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" |