From 5cc9282b31aa85e75552fe6798b91fb4e576338c Mon Sep 17 00:00:00 2001 From: Lars Date: Sat, 4 Jul 2026 19:40:44 +0200 Subject: [PATCH] CI: Deploy und alle Tests in test.yml (needs deploy), separate Deploy-Workflows entfernt. Co-authored-by: Cursor --- .gitea/workflows/deploy-dev.yml | 47 ------- .gitea/workflows/deploy-prod.yml | 47 ------- .gitea/workflows/test.yml | 228 ++++++++++++++++++++++++++----- README.md | 12 +- docs/DEPLOYMENT.md | 11 +- 5 files changed, 206 insertions(+), 139 deletions(-) delete mode 100644 .gitea/workflows/deploy-dev.yml delete mode 100644 .gitea/workflows/deploy-prod.yml diff --git a/.gitea/workflows/deploy-dev.yml b/.gitea/workflows/deploy-dev.yml deleted file mode 100644 index 8b30d97..0000000 --- a/.gitea/workflows/deploy-dev.yml +++ /dev/null @@ -1,47 +0,0 @@ -name: Deploy Development - -on: - push: - branches: [develop] - -jobs: - deploy: - runs-on: ubuntu-latest - steps: - - name: Deploy and verify Development - run: | - set -e - echo "=== Deploying Kairo to DEVELOPMENT ===" - REPO="http://192.168.2.144:3000/Lars/Kairo-Jinkendo.git" - TARGET="/home/lars/docker/kairo-dev" - mkdir -p "$TARGET" - cd "$TARGET" - if [ ! -d .git ]; then - git clone -b develop "$REPO" . - else - git fetch origin develop - git checkout develop - git reset --hard origin/develop - fi - docker compose -f docker-compose.dev-env.yml build --no-cache - docker compose -f docker-compose.dev-env.yml up -d --wait - curl -sf http://localhost:8097/api/health && echo "✓ DEV API /api/health OK" - curl -sf http://localhost:3097/api/health && echo "✓ DEV Frontend-Proxy /api/health OK" - docker compose -f docker-compose.dev-env.yml exec -T backend pip install -q -r requirements-dev.txt - docker compose -f docker-compose.dev-env.yml exec -T backend python -m pytest tests -ra -vv --tb=short - echo "✓ DEV pytest OK" - if command -v k6 >/dev/null 2>&1; then - BASE_URL=http://localhost:8097 k6 run scripts/load/k6-health-baseline.js - echo "✓ DEV k6 OK" - else - echo "(k6 nicht installiert — Health bereits via curl geprüft)" - fi - if command -v node >/dev/null 2>&1; then - npm install --no-audit --no-fund - npx playwright install --with-deps chromium - PLAYWRIGHT_BASE_URL=http://localhost:3097 npx playwright test tests/smoke-health.spec.js - echo "✓ DEV Playwright smoke OK" - else - echo "(Node nicht verfügbar — Playwright übersprungen)" - fi - echo "=== Kairo DEV Deploy complete ===" diff --git a/.gitea/workflows/deploy-prod.yml b/.gitea/workflows/deploy-prod.yml deleted file mode 100644 index 5f62d91..0000000 --- a/.gitea/workflows/deploy-prod.yml +++ /dev/null @@ -1,47 +0,0 @@ -name: Deploy Production - -on: - push: - branches: [main] - -jobs: - deploy: - runs-on: ubuntu-latest - steps: - - name: Deploy and verify Production - run: | - set -e - echo "=== Deploying Kairo to PRODUCTION ===" - REPO="http://192.168.2.144:3000/Lars/Kairo-Jinkendo.git" - TARGET="/home/lars/docker/kairo" - mkdir -p "$TARGET" - cd "$TARGET" - if [ ! -d .git ]; then - git clone -b main "$REPO" . - else - git fetch origin main - git checkout main - git reset --hard origin/main - fi - docker compose build --no-cache - docker compose up -d --wait - curl -sf http://localhost:8004/api/health && echo "✓ PROD API /api/health OK" - curl -sf http://localhost:3004/api/health && echo "✓ PROD Frontend-Proxy /api/health OK" - docker compose exec -T backend pip install -q -r requirements-dev.txt - docker compose exec -T backend python -m pytest tests -ra -vv --tb=short - echo "✓ PROD pytest OK" - if command -v k6 >/dev/null 2>&1; then - BASE_URL=http://localhost:8004 k6 run scripts/load/k6-health-baseline.js - echo "✓ PROD k6 OK" - else - echo "(k6 nicht installiert — Health bereits via curl geprüft)" - fi - if command -v node >/dev/null 2>&1; then - npm install --no-audit --no-fund - npx playwright install --with-deps chromium - PLAYWRIGHT_BASE_URL=http://localhost:3004 npx playwright test tests/smoke-health.spec.js - echo "✓ PROD Playwright smoke OK" - else - echo "(Node nicht verfügbar — Playwright übersprungen)" - fi - echo "=== Kairo PROD Deploy complete ===" diff --git a/.gitea/workflows/test.yml b/.gitea/workflows/test.yml index 35f6336..0d9128f 100644 --- a/.gitea/workflows/test.yml +++ b/.gitea/workflows/test.yml @@ -1,8 +1,7 @@ name: Test Suite -# Bei Push auf develop/main: nur schnelle Checks (Lint + Frontend-Build). -# Vollständige Tests (pytest, k6, Playwright) laufen im Deploy-Workflow -# deploy-dev.yml / deploy-prod.yml — Gitea/act unterstützt workflow_run oft nicht. +# 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] @@ -10,40 +9,6 @@ on: branches: [develop] jobs: - 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}" - - echo "=== Smoke: $COMPOSE (Projekt $COMPOSE_PROJECT_NAME, API $API_PORT) ===" - docker compose -f "$COMPOSE" up -d --build --wait - - curl -sf "http://localhost:${API_PORT}/api/health" - echo "✓ Backend /api/health OK" - - curl -sf "http://localhost:${UI_PORT}/api/health" - echo "✓ Frontend-Proxy /api/health OK" - - 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" - - docker compose -f "$COMPOSE" down -v - lint-backend: runs-on: ubuntu-latest steps: @@ -72,3 +37,192 @@ jobs: 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" diff --git a/README.md b/README.md index 439f92b..ed44039 100644 --- a/README.md +++ b/README.md @@ -64,6 +64,16 @@ Diese Dokumente sind Referenzen, kein direkter Sprint-Scope. Verbindlich ist nur, was über das Kairo Sprint-0 Principle Gate oder eine Architecture Decision übernommen wurde. +## Deployment + +Auto-Deploy und Tests laufen im Workflow **Test Suite** (`.gitea/workflows/test.yml`): + +``` +develop/main push → lint ∥ build → deploy → pytest ∥ k6 ∥ Playwright +``` + +Details: [docs/DEPLOYMENT.md](docs/DEPLOYMENT.md) + ## Local Development Voraussetzungen: Docker + Docker Compose. @@ -87,8 +97,6 @@ docker compose -f docker-compose.dev-env.yml exec backend python -m pytest tests UI: http://localhost:3097 · API: http://localhost:8097 -Deployment (Pi): [docs/DEPLOYMENT.md](docs/DEPLOYMENT.md) - ## AP0.1 – Stand Projektgrundlage | Bereich | Status | diff --git a/docs/DEPLOYMENT.md b/docs/DEPLOYMENT.md index a833aed..6ed2554 100644 --- a/docs/DEPLOYMENT.md +++ b/docs/DEPLOYMENT.md @@ -47,13 +47,12 @@ cp .env.example .env 4. Merge `main` → `deploy-prod.yml` → `curl http://localhost:8004/api/health` 5. Nach Deploy: `test.yml` (workflow_run) — pytest, k6, Playwright smoke gegen **localhost** -| Workflow | Trigger | Inhalt | -|----------|---------|--------| -| `deploy-dev.yml` | Push `develop` | Deploy + Health + pytest + k6/Playwright (falls installiert) | -| `deploy-prod.yml` | Push `main` | Deploy + Health + pytest + k6/Playwright (falls installiert) | -| `test.yml` | Push/PR | Lint + Frontend-Build; PR zusätzlich compose-smoke | +| Workflow | Trigger | Jobs | +|----------|---------|------| +| `test.yml` | Push `develop` / `main` | lint, build → **deploy** → **pytest**, **k6**, **Playwright** | +| `test.yml` | Pull Request | lint, build, compose-smoke (+ pytest) | -Bei Push auf `develop` sind in **Test Suite** nur `lint-backend` und `build-frontend` aktiv — das ist beabsichtigt. Die Integrationstests laufen im Workflow **Deploy Development**. +Alle Integrationstests laufen im **selben** Workflow via `needs: deploy` — kein separates Deploy-Workflow mehr, kein `workflow_run`. ---