name: Docker Build and Test on: push: branches: [ main ] pull_request: branches: [ main ] env: REGISTRY: ghcr.io IMAGE_NAME: ${{ github.repository }} jobs: test: name: Run Tests runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v4 - name: Set up Python 3.10 uses: actions/setup-python@v5 with: python-version: '3.10' cache: 'pip' - name: Install dependencies run: | python -m pip install --upgrade pip pip install -r requirements.txt - name: Run tests with pytest run: | pytest -v --tb=short - name: Generate coverage report if: success() run: | pip install pytest-cov pytest --cov=kiro --cov-report=xml --cov-report=term - name: Upload coverage to artifacts if: success() uses: actions/upload-artifact@v4 with: name: coverage-report path: coverage.xml build: name: Build and Test Docker Image runs-on: ubuntu-latest needs: test permissions: contents: read packages: write security-events: write # For uploading Trivy scan results steps: - name: Checkout code uses: actions/checkout@v4 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Log in to GitHub Container Registry if: github.event_name != 'pull_request' uses: docker/login-action@v3 with: registry: ${{ env.REGISTRY }} username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: Extract metadata for Docker id: meta uses: docker/metadata-action@v5 with: images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} tags: | type=ref,event=branch type=ref,event=pr type=semver,pattern={{version}} type=semver,pattern={{major}}.{{minor}} type=sha,prefix={{branch}}- type=raw,value=latest,enable={{is_default_branch}} - name: Build Docker image uses: docker/build-push-action@v5 with: context: . push: false load: true tags: kiro-gateway:test cache-from: type=gha cache-to: type=gha,mode=max - name: Run Trivy vulnerability scanner uses: aquasecurity/trivy-action@master with: image-ref: kiro-gateway:test format: 'sarif' output: 'trivy-results.sarif' severity: 'CRITICAL,HIGH' exit-code: '0' # Don't fail build, just report - name: Upload Trivy results to GitHub Security uses: github/codeql-action/upload-sarif@v3 if: always() # Upload even if previous step fails with: sarif_file: 'trivy-results.sarif' category: 'docker-image' - name: Test Docker image run: | # Start container with test credentials docker run -d \ --name kiro-gateway-test \ -p 8000:8000 \ -e PROXY_API_KEY="test-key-123" \ -e REFRESH_TOKEN="test-token" \ kiro-gateway:test # Wait for container to be healthy echo "Waiting for container to start..." sleep 10 # Check if container is running docker ps -a # Check container logs echo "Container logs:" docker logs kiro-gateway-test # Test 1: Health endpoint (no auth required) echo "Testing health endpoint..." curl -f http://localhost:8000/health || exit 1 # Test 2: Root endpoint (no auth required) echo "Testing root endpoint..." curl -f http://localhost:8000/ || exit 1 # Test 3: Models endpoint with authentication echo "Testing models endpoint with auth..." curl -f -H "Authorization: Bearer test-key-123" \ http://localhost:8000/v1/models || exit 1 # Test 4: Verify container hasn't restarted RESTARTS=$(docker inspect -f '{{.RestartCount}}' kiro-gateway-test) echo "Container restart count: $RESTARTS" if [ "$RESTARTS" -ne 0 ]; then echo "ERROR: Container restarted $RESTARTS times" exit 1 fi # Test 5: Check for errors in logs echo "Checking logs for errors..." if docker logs kiro-gateway-test 2>&1 | grep -i "error" | grep -v "ERROR.*404"; then echo "WARNING: Found errors in logs (non-404)" fi # Cleanup docker stop kiro-gateway-test docker rm kiro-gateway-test - name: Build and push Docker image if: github.event_name != 'pull_request' uses: docker/build-push-action@v5 with: context: . platforms: linux/amd64,linux/arm64 # Multi-arch support (x86_64 and ARM64) push: true tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} cache-from: type=gha cache-to: type=gha,mode=max - name: Image digest if: github.event_name != 'pull_request' run: echo ${{ steps.meta.outputs.digest }}