name: Integration Test on: pull_request: branches: [ "main" ] workflow_dispatch: {} concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true jobs: # ── Job 1: Platform Conformance ─────────────────────────────────────────── platform-check: name: Platform Conformance runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v4 - name: Validate catalog-info.yaml run: | if [ ! -f catalog-info.yaml ]; then echo "✗ catalog-info.yaml not found" exit 1 fi python3 -c "import yaml; list(yaml.safe_load_all(open('catalog-info.yaml')))" 2>/dev/null \ || (pip install pyyaml -q && python3 -c "import yaml; list(yaml.safe_load_all(open('catalog-info.yaml')))") echo "✓ catalog-info.yaml is valid YAML" - name: Check platform initialized run: | if [ -f ".platform/initialized.md" ]; then echo "✓ Platform initialized" else echo "⚠ .platform/initialized.md not found — skipping guard" fi # ── Job 2: Unit Tests + Container Smoke ─────────────────────────────────── smoke-test: name: Unit Tests + Container Smoke runs-on: ubuntu-latest needs: platform-check timeout-minutes: 20 steps: - name: Checkout uses: actions/checkout@v4 - name: Free disk space run: | docker system prune -f 2>/dev/null || true df -h / 2>/dev/null || true - name: Install Docker CLI run: command -v docker &>/dev/null || (apt-get update -qq && apt-get install -y docker.io) - name: Build container image run: | if [ -f Dockerfile ]; then docker build -t ci-image:test . else echo "No Dockerfile found — skipping container smoke test" echo "SKIP_SMOKE=true" >> $GITHUB_ENV fi - name: Start service and wait for health if: env.SKIP_SMOKE != 'true' run: | CONTAINER_NAME="ci-${GITHUB_RUN_ID}" PORT="${CONTAINER_PORT:-8080}" HEALTH_PATH="${HEALTH_ENDPOINT:-/health}" echo "CONTAINER_NAME=${CONTAINER_NAME}" >> $GITHUB_ENV echo "CONTAINER_PORT=${PORT}" >> $GITHUB_ENV echo "HEALTH_PATH=${HEALTH_PATH}" >> $GITHUB_ENV docker run -d --name "${CONTAINER_NAME}" -e OTEL_SDK_DISABLED=true ci-image:test for i in $(seq 1 10); do CONTAINER_IP=$(docker inspect "${CONTAINER_NAME}" --format '{{.NetworkSettings.IPAddress}}' 2>/dev/null) [ -n "${CONTAINER_IP}" ] && break sleep 1 done echo "CONTAINER_IP=${CONTAINER_IP}" >> $GITHUB_ENV echo "Waiting for ${HEALTH_PATH} on ${CONTAINER_IP}:${PORT} (up to 180s)..." DEADLINE=$(($(date +%s) + 180)) while true; do if curl -sf "http://${CONTAINER_IP}:${PORT}${HEALTH_PATH}" >/dev/null 2>&1; then break fi if [ $(date +%s) -ge $DEADLINE ]; then echo "Timeout waiting for health check" docker logs "${CONTAINER_NAME}" 2>&1 | tail -30 exit 1 fi if ! docker ps --filter "name=${CONTAINER_NAME}" --format '{{.Status}}' | grep -q Up; then echo "Container exited:" docker logs "${CONTAINER_NAME}" 2>&1 | tail -30 exit 1 fi echo " still waiting..."; sleep 3 done echo "✓ Service healthy at ${CONTAINER_IP}:${PORT}${HEALTH_PATH}" - name: Validate health response if: env.SKIP_SMOKE != 'true' run: | curl -sf "http://${CONTAINER_IP}:${CONTAINER_PORT}${HEALTH_PATH}" > /tmp/health.json echo "Health response:" cat /tmp/health.json echo "" echo "✓ Container smoke test: PASSED" - name: Cleanup if: always() run: docker rm -f "ci-${GITHUB_RUN_ID}" 2>/dev/null || true - name: Post commit status if: always() env: GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }} JOB_STATUS: ${{ job.status }} run: | STATE=$([[ "$JOB_STATUS" == "success" ]] && echo "success" || echo "failure") DESC=$([[ "$STATE" == "success" ]] && echo "All checks passed" || echo "Some checks failed") curl -sf -X POST \ -H "Authorization: token ${GITEA_TOKEN}" \ -H "Content-Type: application/json" \ "${GITHUB_SERVER_URL}/api/v1/repos/${GITHUB_REPOSITORY}/statuses/${GITHUB_SHA}" \ -d "{\"state\":\"${STATE}\",\"context\":\"Integration Test / Unit Tests + Container Smoke (workflow_dispatch)\",\"description\":\"${DESC}\"}" \ || true