CI: Integrationstests in Deploy-Workflow, Test Suite nur Lint/Build bei Push.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
b1e00bb347
commit
486268efd9
|
|
@ -8,7 +8,7 @@ jobs:
|
||||||
deploy:
|
deploy:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Deploy to Development
|
- name: Deploy and verify Development
|
||||||
run: |
|
run: |
|
||||||
set -e
|
set -e
|
||||||
echo "=== Deploying Kairo to DEVELOPMENT ==="
|
echo "=== Deploying Kairo to DEVELOPMENT ==="
|
||||||
|
|
@ -26,10 +26,22 @@ jobs:
|
||||||
docker compose -f docker-compose.dev-env.yml build --no-cache
|
docker compose -f docker-compose.dev-env.yml build --no-cache
|
||||||
docker compose -f docker-compose.dev-env.yml up -d --wait
|
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:8097/api/health && echo "✓ DEV API /api/health OK"
|
||||||
if docker compose -f docker-compose.dev-env.yml ps --status running 2>/dev/null | grep -q frontend; then
|
|
||||||
curl -sf http://localhost:3097/api/health && echo "✓ DEV Frontend-Proxy /api/health OK"
|
curl -sf http://localhost:3097/api/health && echo "✓ DEV Frontend-Proxy /api/health OK"
|
||||||
fi
|
|
||||||
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 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
|
docker compose -f docker-compose.dev-env.yml exec -T backend python -m pytest tests -ra -vv --tb=short
|
||||||
echo "✓ DEV pytest OK"
|
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 ==="
|
echo "=== Kairo DEV Deploy complete ==="
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ jobs:
|
||||||
deploy:
|
deploy:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Deploy to Production
|
- name: Deploy and verify Production
|
||||||
run: |
|
run: |
|
||||||
set -e
|
set -e
|
||||||
echo "=== Deploying Kairo to PRODUCTION ==="
|
echo "=== Deploying Kairo to PRODUCTION ==="
|
||||||
|
|
@ -26,10 +26,22 @@ jobs:
|
||||||
docker compose build --no-cache
|
docker compose build --no-cache
|
||||||
docker compose up -d --wait
|
docker compose up -d --wait
|
||||||
curl -sf http://localhost:8004/api/health && echo "✓ PROD API /api/health OK"
|
curl -sf http://localhost:8004/api/health && echo "✓ PROD API /api/health OK"
|
||||||
if docker compose ps --status running 2>/dev/null | grep -q frontend; then
|
|
||||||
curl -sf http://localhost:3004/api/health && echo "✓ PROD Frontend-Proxy /api/health OK"
|
curl -sf http://localhost:3004/api/health && echo "✓ PROD Frontend-Proxy /api/health OK"
|
||||||
fi
|
|
||||||
docker compose exec -T backend pip install -q -r requirements-dev.txt
|
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
|
docker compose exec -T backend python -m pytest tests -ra -vv --tb=short
|
||||||
echo "✓ PROD pytest OK"
|
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 ==="
|
echo "=== Kairo PROD Deploy complete ==="
|
||||||
|
|
|
||||||
|
|
@ -1,20 +1,16 @@
|
||||||
name: Test Suite
|
name: Test Suite
|
||||||
|
|
||||||
# push develop/main → nur lint + frontend-build (Deploy läuft separat)
|
# Bei Push auf develop/main: nur schnelle Checks (Lint + Frontend-Build).
|
||||||
# pull_request → compose-smoke auf alternativen Ports (kein Konflikt mit kairo-dev)
|
# Vollständige Tests (pytest, k6, Playwright) laufen im Deploy-Workflow
|
||||||
# workflow_run nach Deploy → pytest/k6/playwright gegen deployte Instanz (localhost)
|
# deploy-dev.yml / deploy-prod.yml — Gitea/act unterstützt workflow_run oft nicht.
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches: [develop, main]
|
branches: [develop, main]
|
||||||
pull_request:
|
pull_request:
|
||||||
branches: [develop]
|
branches: [develop]
|
||||||
workflow_run:
|
|
||||||
workflows: ["Deploy Development", "Deploy Production"]
|
|
||||||
types: [completed]
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
compose-smoke:
|
compose-smoke:
|
||||||
# Nicht bei push: Deploy nutzt dieselben Standard-Ports auf dem Pi.
|
|
||||||
if: github.event_name == 'pull_request'
|
if: github.event_name == 'pull_request'
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
env:
|
env:
|
||||||
|
|
@ -36,10 +32,10 @@ jobs:
|
||||||
echo "=== Smoke: $COMPOSE (Projekt $COMPOSE_PROJECT_NAME, API $API_PORT) ==="
|
echo "=== Smoke: $COMPOSE (Projekt $COMPOSE_PROJECT_NAME, API $API_PORT) ==="
|
||||||
docker compose -f "$COMPOSE" up -d --build --wait
|
docker compose -f "$COMPOSE" up -d --build --wait
|
||||||
|
|
||||||
curl -sf "http://localhost:${API_PORT}/api/health" | tee /tmp/health-api.json
|
curl -sf "http://localhost:${API_PORT}/api/health"
|
||||||
echo "✓ Backend /api/health OK"
|
echo "✓ Backend /api/health OK"
|
||||||
|
|
||||||
curl -sf "http://localhost:${UI_PORT}/api/health" | tee /tmp/health-ui.json
|
curl -sf "http://localhost:${UI_PORT}/api/health"
|
||||||
echo "✓ Frontend-Proxy /api/health OK"
|
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 pip install -q -r requirements-dev.txt
|
||||||
|
|
@ -48,66 +44,18 @@ jobs:
|
||||||
|
|
||||||
docker compose -f "$COMPOSE" down -v
|
docker compose -f "$COMPOSE" down -v
|
||||||
|
|
||||||
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
|
|
||||||
RUN_WORKFLOW="${{ github.event.workflow_run.name }}"
|
|
||||||
if [ "$RUN_WORKFLOW" = "Deploy Production" ]; then
|
|
||||||
APP_DIR="/home/lars/docker/kairo"
|
|
||||||
COMPOSE_FILE="docker-compose.yml"
|
|
||||||
else
|
|
||||||
APP_DIR="/home/lars/docker/kairo-dev"
|
|
||||||
COMPOSE_FILE="docker-compose.dev-env.yml"
|
|
||||||
fi
|
|
||||||
|
|
||||||
cd "$APP_DIR"
|
|
||||||
for i in $(seq 1 60); do
|
|
||||||
if docker compose -f "$COMPOSE_FILE" exec -T backend true 2>/dev/null; then
|
|
||||||
break
|
|
||||||
fi
|
|
||||||
if [ "$i" -eq 60 ]; then
|
|
||||||
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
|
|
||||||
"
|
|
||||||
|
|
||||||
lint-backend:
|
lint-backend:
|
||||||
if: github.event_name == 'push' || github.event_name == 'pull_request' || (github.event_name == 'workflow_run' && github.event.workflow_run.conclusion == 'success')
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
if: github.event_name != 'workflow_run'
|
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Check backend syntax (Checkout)
|
- name: Check backend syntax
|
||||||
if: github.event_name != 'workflow_run'
|
|
||||||
run: python3 -m py_compile backend/main.py backend/run_migrations.py backend/db.py
|
|
||||||
|
|
||||||
- name: Check backend syntax (Deploy-Pfad)
|
|
||||||
if: github.event_name == 'workflow_run'
|
|
||||||
run: |
|
run: |
|
||||||
RUN_WORKFLOW="${{ github.event.workflow_run.name }}"
|
python3 -m py_compile backend/main.py backend/run_migrations.py backend/db.py
|
||||||
if [ "$RUN_WORKFLOW" = "Deploy Production" ]; then
|
|
||||||
APP_DIR="/home/lars/docker/kairo"
|
|
||||||
else
|
|
||||||
APP_DIR="/home/lars/docker/kairo-dev"
|
|
||||||
fi
|
|
||||||
python3 -m py_compile "$APP_DIR/backend/main.py"
|
|
||||||
echo "✓ Backend syntax OK"
|
echo "✓ Backend syntax OK"
|
||||||
|
|
||||||
build-frontend:
|
build-frontend:
|
||||||
if: github.event_name == 'push' || github.event_name == 'pull_request'
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
|
|
@ -124,94 +72,3 @@ jobs:
|
||||||
npm install
|
npm install
|
||||||
npm run build
|
npm run build
|
||||||
echo "✓ Frontend build OK"
|
echo "✓ Frontend build 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 (localhost auf Runner)
|
|
||||||
id: k6
|
|
||||||
run: |
|
|
||||||
if [ "${{ github.event.workflow_run.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 60); 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: |
|
|
||||||
if [ "${{ github.event.workflow_run.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 60); 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 smoke tests
|
|
||||||
env:
|
|
||||||
PLAYWRIGHT_BASE_URL: ${{ steps.pw.outputs.base_url }}
|
|
||||||
run: npx playwright test tests/smoke-health.spec.js
|
|
||||||
|
|
|
||||||
|
|
@ -47,13 +47,13 @@ cp .env.example .env
|
||||||
4. Merge `main` → `deploy-prod.yml` → `curl http://localhost:8004/api/health`
|
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**
|
5. Nach Deploy: `test.yml` (workflow_run) — pytest, k6, Playwright smoke gegen **localhost**
|
||||||
|
|
||||||
| Workflow | Trigger |
|
| Workflow | Trigger | Inhalt |
|
||||||
|----------|---------|
|
|----------|---------|--------|
|
||||||
| `deploy-dev.yml` | Push `develop` |
|
| `deploy-dev.yml` | Push `develop` | Deploy + Health + pytest + k6/Playwright (falls installiert) |
|
||||||
| `deploy-prod.yml` | Push `main` |
|
| `deploy-prod.yml` | Push `main` | Deploy + Health + pytest + k6/Playwright (falls installiert) |
|
||||||
| `test.yml` | Push/PR (compose-smoke) + nach Deploy (Integration) |
|
| `test.yml` | Push/PR | Lint + Frontend-Build; PR zusätzlich compose-smoke |
|
||||||
|
|
||||||
CI auf dem Pi nutzt localhost-Ports. Öffentliche Domains sind für Reverse-Proxy optional.
|
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**.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user