name: Test Suite # Push develop/main: deploy → pytest, k6, Playwright (needs deploy, gleicher Workflow) # Pull Request: compose-smoke auf isolierten Ports (kein Konflikt mit kairo-dev) on: push: branches: [develop, main] pull_request: branches: [develop] jobs: lint-backend: runs-on: ubuntu-latest steps: - name: Checkout repository uses: actions/checkout@v4 - name: Check backend syntax run: | python3 -m py_compile backend/main.py backend/run_migrations.py backend/db.py echo "✓ Backend syntax OK" build-frontend: 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: Build frontend run: | cd frontend npm install npm run build echo "✓ Frontend build OK" deploy: if: github.event_name == 'push' runs-on: ubuntu-latest steps: - name: Deploy to target environment run: | set -e REPO="http://192.168.2.144:3000/Lars/Kairo-Jinkendo.git" if [ "${{ github.ref_name }}" = "main" ]; then TARGET="/home/lars/docker/kairo" BRANCH="main" COMPOSE="docker-compose.yml" API_PORT=8004 UI_PORT=3004 echo "=== Deploy PRODUCTION ===" else TARGET="/home/lars/docker/kairo-dev" BRANCH="develop" COMPOSE="docker-compose.dev-env.yml" API_PORT=8097 UI_PORT=3097 echo "=== Deploy DEVELOPMENT ===" fi mkdir -p "$TARGET" cd "$TARGET" if [ ! -d .git ]; then git clone -b "$BRANCH" "$REPO" . else git fetch origin "$BRANCH" git checkout "$BRANCH" git reset --hard "origin/$BRANCH" fi docker compose -f "$COMPOSE" build --no-cache docker compose -f "$COMPOSE" up -d --wait curl -sf "http://localhost:${API_PORT}/api/health" && echo "✓ API /api/health OK" curl -sf "http://localhost:${UI_PORT}/api/health" && echo "✓ Frontend-Proxy /api/health OK" echo "DEPLOY_TARGET=$TARGET" >> "$GITHUB_ENV" echo "DEPLOY_COMPOSE=$COMPOSE" >> "$GITHUB_ENV" echo "DEPLOY_API_PORT=$API_PORT" >> "$GITHUB_ENV" echo "DEPLOY_UI_PORT=$UI_PORT" >> "$GITHUB_ENV" 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: Compose Stack bauen und testen (isolierte CI-Ports) run: | set -e COMPOSE="docker-compose.dev-env.yml" API_PORT="${KAIRO_BACKEND_PORT}" UI_PORT="${KAIRO_FRONTEND_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 "✓ PR compose-smoke + pytest OK" pytest-backend: if: github.event_name == 'push' needs: [deploy] runs-on: ubuntu-latest steps: - name: Backend pytest im deployten Container run: | set -e if [ "${{ github.ref_name }}" = "main" ]; then APP_DIR="/home/lars/docker/kairo" COMPOSE="docker-compose.yml" else APP_DIR="/home/lars/docker/kairo-dev" COMPOSE="docker-compose.dev-env.yml" fi cd "$APP_DIR" for i in $(seq 1 60); do if docker compose -f "$COMPOSE" exec -T backend true 2>/dev/null; then echo "Backend bereit (Versuch $i)" break fi if [ "$i" -eq 60 ]; then docker compose -f "$COMPOSE" ps || true docker compose -f "$COMPOSE" logs backend --tail 80 || true exit 1 fi sleep 5 done 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 echo "✓ pytest OK" k6-health-baseline: name: k6 /api/health Baseline if: github.event_name == 'push' needs: [deploy] runs-on: ubuntu-latest steps: - name: k6 gegen deployte Instanz (localhost) run: | set -e if [ "${{ github.ref_name }}" = "main" ]; then APP_DIR="/home/lars/docker/kairo" BASE_URL="http://localhost:8004" else APP_DIR="/home/lars/docker/kairo-dev" BASE_URL="http://localhost:8097" fi for i in $(seq 1 30); do if curl -sf "$BASE_URL/api/health" >/dev/null 2>&1; then break fi if [ "$i" -eq 30 ]; then curl -v "$BASE_URL/api/health" || true exit 1 fi sleep 2 done cd "$APP_DIR" K6_VER="v0.55.0" if ! command -v k6 >/dev/null 2>&1; then 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 fi BASE_URL="$BASE_URL" k6 run scripts/load/k6-health-baseline.js echo "✓ k6 OK" playwright-smoke: if: github.event_name == 'push' needs: [deploy] runs-on: ubuntu-latest steps: - name: Playwright smoke gegen deployte Instanz run: | set -e if [ "${{ github.ref_name }}" = "main" ]; then APP_DIR="/home/lars/docker/kairo" BASE_URL="http://localhost:3004" else APP_DIR="/home/lars/docker/kairo-dev" BASE_URL="http://localhost:3097" fi for i in $(seq 1 30); do if curl -sf "$BASE_URL/api/health" >/dev/null 2>&1; then break fi if [ "$i" -eq 30 ]; then exit 1 fi sleep 2 done cd "$APP_DIR" if ! command -v node >/dev/null 2>&1; then echo "Fehler: Node.js auf dem Runner erforderlich für Playwright." exit 1 fi npm install --no-audit --no-fund npx playwright install --with-deps chromium PLAYWRIGHT_BASE_URL="$BASE_URL" npx playwright test tests/smoke-health.spec.js echo "✓ Playwright smoke OK"