name: Test Suite # develop: push/PR → Tests gegen deployte Dev-Instanz (wartet auf Container). # main: kein push/PR — Prod-Tests via workflow_run nach Deploy Production. # compose-smoke (PR): eigener Stack auf CI-Ports 18197/13197 (kein Konflikt mit kairo-dev). on: push: branches: [develop] pull_request: branches: [develop] workflow_run: workflows: ["Deploy Development", "Deploy Production"] types: [completed] jobs: pytest-backend: if: ${{ github.event_name != 'workflow_run' || github.event.workflow_run.conclusion == 'success' }} runs-on: ubuntu-latest steps: - name: Backend pytest im deployten Container run: | set -e EVENT_NAME="${{ github.event_name }}" REF_NAME="${{ github.ref_name }}" BASE_REF="${{ github.base_ref }}" RUN_WORKFLOW="${{ github.event.workflow_run.name }}" APP_DIR="/home/lars/docker/kairo" COMPOSE_FILE="docker-compose.yml" if [ "$EVENT_NAME" = "workflow_run" ]; then if [ "$RUN_WORKFLOW" = "Deploy Development" ]; then APP_DIR="/home/lars/docker/kairo-dev" COMPOSE_FILE="docker-compose.dev-env.yml" fi elif [ "$REF_NAME" = "develop" ] || [ "$BASE_REF" = "develop" ]; then APP_DIR="/home/lars/docker/kairo-dev" COMPOSE_FILE="docker-compose.dev-env.yml" fi cd "$APP_DIR" echo "Warte auf stabilen backend-Container …" for i in $(seq 1 60); do if docker compose -f "$COMPOSE_FILE" exec -T backend true 2>/dev/null; then echo "Backend bereit (Versuch $i)" break fi if [ "$i" -eq 60 ]; then echo "Timeout: backend-Container nicht bereit" docker compose -f "$COMPOSE_FILE" ps || true docker compose -f "$COMPOSE_FILE" logs backend --tail 80 || true exit 1 fi sleep 5 done docker compose -f "$COMPOSE_FILE" exec -T backend sh -lc " pip install -q -r requirements-dev.txt && python -m pytest tests -ra -vv --tb=short " echo "✓ pytest OK" lint-backend: if: ${{ github.event_name != 'workflow_run' || github.event.workflow_run.conclusion == 'success' }} runs-on: ubuntu-latest steps: - name: Checkout repository if: github.event_name != 'workflow_run' uses: actions/checkout@v4 - name: Check backend syntax (Checkout) if: github.event_name != 'workflow_run' run: | python3 -m py_compile backend/main.py backend/run_migrations.py backend/db.py echo "✓ Backend syntax OK" - name: Check backend syntax (Deploy-Pfad) if: github.event_name == 'workflow_run' run: | RUN_WORKFLOW="${{ github.event.workflow_run.name }}" if [ "$RUN_WORKFLOW" = "Deploy Development" ]; then APP_DIR="/home/lars/docker/kairo-dev" else APP_DIR="/home/lars/docker/kairo" fi python3 -m py_compile "$APP_DIR/backend/main.py" echo "✓ Backend syntax OK" compose-smoke: if: github.event_name == 'pull_request' runs-on: ubuntu-latest env: COMPOSE_PROJECT_NAME: kairo-ci-smoke DB_PASSWORD: ci_smoke_password KAIRO_BACKEND_PORT: 18197 KAIRO_FRONTEND_PORT: 13197 steps: - name: Checkout repository uses: actions/checkout@v4 - name: Isolierter Stack (CI-Ports, kein Konflikt mit kairo-dev) run: | set -e COMPOSE="docker-compose.dev-env.yml" API_PORT="${KAIRO_BACKEND_PORT}" UI_PORT="${KAIRO_FRONTEND_PORT}" echo "compose-smoke auf localhost:${API_PORT} / ${UI_PORT}" docker compose -f "$COMPOSE" up -d --build --wait curl -sf "http://localhost:${API_PORT}/api/health" curl -sf "http://localhost:${UI_PORT}/api/health" docker compose -f "$COMPOSE" exec -T backend pip install -q -r requirements-dev.txt docker compose -f "$COMPOSE" exec -T backend python -m pytest tests -ra -vv --tb=short docker compose -f "$COMPOSE" down -v echo "✓ compose-smoke OK" k6-health-baseline: name: k6 /api/health Baseline if: ${{ github.event_name != 'workflow_run' || github.event.workflow_run.conclusion == 'success' }} runs-on: ubuntu-latest steps: - name: Checkout repository uses: actions/checkout@v4 - name: k6-Ziel wählen id: k6 run: | EVENT="${{ github.event_name }}" WF_NAME="${{ github.event.workflow_run.name }}" if [ "$EVENT" = "workflow_run" ] && [ "$WF_NAME" = "Deploy Production" ]; then echo "base_url=http://localhost:8004" >> $GITHUB_OUTPUT else echo "base_url=http://localhost:8097" >> $GITHUB_OUTPUT fi - name: /api/health abwarten run: | BASE="${{ steps.k6.outputs.base_url }}" for i in $(seq 1 90); do if curl -sf "$BASE/api/health" >/dev/null 2>&1; then echo "Health OK (Versuch $i)" exit 0 fi sleep 2 done curl -v "$BASE/api/health" || true exit 1 - name: Install k6 run: | set -e K6_VER="v0.55.0" ARCH=$(uname -m) case "$ARCH" in x86_64) K6_ARCH=amd64 ;; aarch64|arm64) K6_ARCH=arm64 ;; *) echo "k6: unbekannte Architektur: $ARCH"; exit 1 ;; esac curl -sSL "https://github.com/grafana/k6/releases/download/${K6_VER}/k6-${K6_VER}-linux-${K6_ARCH}.tar.gz" -o /tmp/k6.tgz tar -xzf /tmp/k6.tgz -C /tmp sudo mv "/tmp/k6-${K6_VER}-linux-${K6_ARCH}/k6" /usr/local/bin/k6 - name: k6 Health-Baseline env: BASE_URL: ${{ steps.k6.outputs.base_url }} run: k6 run scripts/load/k6-health-baseline.js playwright-smoke: if: ${{ github.event_name != 'workflow_run' || github.event.workflow_run.conclusion == 'success' }} runs-on: ubuntu-latest steps: - name: Checkout repository uses: actions/checkout@v4 - name: Setup Node.js uses: actions/setup-node@v4 with: node-version: "20" - name: Playwright-Ziel wählen id: pw run: | EVENT="${{ github.event_name }}" WF_NAME="${{ github.event.workflow_run.name }}" if [ "$EVENT" = "workflow_run" ] && [ "$WF_NAME" = "Deploy Production" ]; then echo "base_url=http://localhost:3004" >> $GITHUB_OUTPUT else echo "base_url=http://localhost:3097" >> $GITHUB_OUTPUT fi - name: /api/health abwarten run: | BASE="${{ steps.pw.outputs.base_url }}" for i in $(seq 1 90); do if curl -sf "$BASE/api/health" >/dev/null 2>&1; then exit 0 fi sleep 2 done exit 1 - name: Install Playwright run: | npm install npx playwright install --with-deps chromium - name: Run Playwright smoke env: PLAYWRIGHT_BASE_URL: ${{ steps.pw.outputs.base_url }} run: npx playwright test tests/smoke-health.spec.js