diff --git a/.gitea/workflows/test.yml b/.gitea/workflows/test.yml index 5a09570..dd1bd90 100644 --- a/.gitea/workflows/test.yml +++ b/.gitea/workflows/test.yml @@ -88,6 +88,90 @@ jobs: npm run build echo "✓ Frontend build OK" + # Phase-0 Lastsmoke: nur k6 — eigener Job (kein Node/Playwright), klare CI-Zuordnung. + k6-health-baseline: + name: k6 /health Baseline + if: ${{ github.event_name != 'workflow_run' || github.event.workflow_run.conclusion == 'success' }} + runs-on: ubuntu-latest + env: + E2E_TARGET_URL: https://dev.shinkan.jinkendo.de + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: E2E-Ziel wählen (Dev über Proxy vs. Production) + id: e2e + run: | + EVENT="${{ github.event_name }}" + WF_NAME="${{ github.event.workflow_run.name }}" + DEV_BASE="${{ env.E2E_TARGET_URL }}" + if [ "$EVENT" = "workflow_run" ] && [ "$WF_NAME" = "Deploy Production" ]; then + echo "mode=prod" >> $GITHUB_OUTPUT + echo "base_url=https://shinkan.jinkendo.de" >> $GITHUB_OUTPUT + echo "→ k6 gegen Prod-Basis." + else + echo "mode=dev" >> $GITHUB_OUTPUT + echo "base_url=${DEV_BASE}" >> $GITHUB_OUTPUT + echo "→ k6 gegen Dev (${DEV_BASE})." + fi + + - name: Dev /health abwarten + if: ${{ steps.e2e.outputs.mode == 'dev' }} + run: | + BASE="${{ steps.e2e.outputs.base_url }}" + echo "Warte auf $BASE/health …" + for i in $(seq 1 90); do + if curl -sf "$BASE/health" >/dev/null 2>&1; then + echo "Health OK (Versuch $i)" + exit 0 + fi + sleep 2 + done + echo "Timeout: Dev /health nicht erreichbar — Deploy / DNS / Firewall prüfen." + curl -v "$BASE/health" || true + exit 1 + + - name: Prod /health abwarten + if: ${{ steps.e2e.outputs.mode == 'prod' }} + run: | + BASE="${{ steps.e2e.outputs.base_url }}" + echo "Warte auf $BASE/health …" + for i in $(seq 1 60); do + if curl -sf "$BASE/health" >/dev/null 2>&1; then + echo "Health OK (Versuch $i)" + exit 0 + fi + sleep 5 + done + echo "Timeout: Prod /health nicht erreichbar" + curl -v "$BASE/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 + echo "Installing k6 ${K6_VER} linux-${K6_ARCH}" + 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 + k6 version + + - name: k6 Health-Baseline (parallele /health) + env: + BASE_URL: ${{ steps.e2e.outputs.base_url }} + run: | + set -e + echo "k6 gegen BASE_URL=$BASE_URL" + k6 run scripts/load/k6-health-baseline.js + echo "✓ k6 Health-Baseline passed" + playwright-tests: if: ${{ github.event_name != 'workflow_run' || github.event.workflow_run.conclusion == 'success' }} runs-on: ubuntu-latest @@ -153,31 +237,6 @@ jobs: curl -v "$BASE/health" || true exit 1 - - name: Install k6 (Phase-0 /health-Baseline) - 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 - echo "Installing k6 ${K6_VER} linux-${K6_ARCH}" - 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 - k6 version - - - name: k6 Health-Baseline (parallele /health) - env: - BASE_URL: ${{ steps.e2e.outputs.base_url }} - run: | - set -e - echo "k6 gegen BASE_URL=$BASE_URL" - k6 run scripts/load/k6-health-baseline.js - echo "✓ k6 Health-Baseline passed" - - name: Testnutzer registrieren (Dev, nur wenn möglich) if: ${{ steps.e2e.outputs.mode == 'dev' }} env: diff --git a/docs/architecture/BASELINE_SNAPSHOT.md b/docs/architecture/BASELINE_SNAPSHOT.md index 5c1ad0a..924cd78 100644 --- a/docs/architecture/BASELINE_SNAPSHOT.md +++ b/docs/architecture/BASELINE_SNAPSHOT.md @@ -78,7 +78,7 @@ Messung: Repo-Root → `cd frontend && npm run build` (Vite Production). ### 3.2 k6 – parallele /health - **Skript:** `scripts/load/k6-health-baseline.js` -- **CI:** Läuft **automatisch** im Gitea-Workflow **playwright-tests** nach der Health-Wartezeit und **vor** Playwright (`.gitea/workflows/test.yml`). +- **CI:** Läuft **automatisch** im Gitea-Workflow im Job **`k6-health-baseline`** (eigenständig, ohne Playwright; `.gitea/workflows/test.yml`). Parallel dazu **Playwright** im Job **`playwright-tests`**. - **Lokal:** siehe `scripts/load/README.md` - **Baseline notieren:** k6-Ausgabe `http_req_duration` p(95), Checks succeeded. diff --git a/docs/architecture/README.md b/docs/architecture/README.md index a362ea2..ac5fe6c 100644 --- a/docs/architecture/README.md +++ b/docs/architecture/README.md @@ -14,7 +14,7 @@ Dieses Bündel ist die **Leitlinie für die große Refaktorierung** nach dem MVP ## Tests (E2E / Refaktor-Budget) -- **`tests/dev-smoke-test.spec.js`** – Playwright-Suite (Smoke + Compliance). Enthält u. a. **Test 8:** nach Login und **Reload** des Dashboards werden GET-Aufrufe zu `/api/profiles/me` und `/api/training-units` gezählt (Absicherung Dashboard-Refaktor Phase 1). Ausführung: `npm run test:e2e`; CI: `.gitea/workflows/test.yml` Job **playwright-tests**. +- **`tests/dev-smoke-test.spec.js`** – Playwright-Suite (Smoke + Compliance). Enthält u. a. **Test 8:** nach Login und **Reload** des Dashboards werden GET-Aufrufe zu `/api/profiles/me` und `/api/training-units` gezählt (Absicherung Dashboard-Refaktor Phase 1). Ausführung: `npm run test:e2e`; CI: `.gitea/workflows/test.yml` Job **playwright-tests**. **k6**-Baseline: Job **`k6-health-baseline`** (siehe `scripts/load/README.md`). ## Pflege diff --git a/scripts/load/README.md b/scripts/load/README.md index 39f920c..623954b 100644 --- a/scripts/load/README.md +++ b/scripts/load/README.md @@ -2,7 +2,7 @@ Parallele GETs auf `/health` – **ohne** Auth, geeignet für Dev/Prod hinter dem gleichen Proxy wie die App. -**CI / Deploy:** In **`.gitea/workflows/test.yml`** (Job `playwright-tests`): nach **/health-Wartezeit** läuft **k6** automatisch, danach Playwright. Gleiche `BASE_URL` wie E2E (Dev oder Prod nach `workflow_run`). Kein manueller Schritt nach dem Deploy. +**CI / Deploy:** In **`.gitea/workflows/test.yml`** eigener Job **`k6-health-baseline`** (nur Checkout + /health-Wartezeit + k6). **Playwright** läuft parallel/im selben Workflow im Job **`playwright-tests`** — ohne k6. Gleiche `BASE_URL`-Logik (Dev oder Prod nach `workflow_run`). ## Voraussetzung