name: Backend E2E # Fuehrt `npm run test:e2e` (Jest, maxWorkers 4, siehe test/jest-e2e.json) # gegen einen frischen Postgres-Service-Container aus. Das Backend-Image # (backend-image.yml) fuehrt nur Lint, Typecheck und Unit-Tests aus, weil der # Docker-Build keine Datenbank hat; diese Pipeline schliesst die Luecke. on: push: paths: - "ApiCore-Backend/**" - ".gitea/workflows/backend-e2e.yml" workflow_dispatch: # Ein neuer Push auf denselben Ref ersetzt den laufenden Lauf. concurrency: group: backend-e2e-${{ gitea.ref }} cancel-in-progress: true jobs: e2e: runs-on: docker-builder timeout-minutes: 30 # Gitea act_runner unterstuetzt `services:`. Annahme (beim ersten Lauf # pruefen): der Job-Container teilt das Netz der Services und erreicht # Postgres unter dem Service-Namen `postgres`. Laeuft der Runner # stattdessen im Host-Modus, ist der Port auf localhost veroeffentlicht; # der Schritt "Datenbank-Host ermitteln" probiert beide Wege. services: postgres: # Gleiche Major-Version wie Produktion (deploy/k8s/base/postgres). # Per Digest gepinnt (Index-Digest von 18.6-alpine, nachgeschlagen # 2026-10-16); die k8s-Manifeste pinnen Postgres bisher nur per Tag. image: postgres:18.6-alpine@sha256:77f585114c32fbca283dc835b0596f4e52b51b4c6662d7810b2f4084f60a1873 env: # Wegwerf-Datenbank im Service-Container, nur im Job-Netz erreichbar # und nach dem Lauf verworfen: kein echtes Secret. POSTGRES_USER: apicore POSTGRES_PASSWORD: apicore-ci-only POSTGRES_DB: apicore_test ports: - 5432:5432 options: >- --health-cmd "pg_isready -U apicore -d apicore_test" --health-interval 5s --health-timeout 5s --health-retries 20 env: NODE_ENV: test # Das Wetter-e2e ruft die echte Open-Meteo-API; in CI ueberspringen. SKIP_EXTERNAL: "1" JWT_ACCESS_EXPIRES_IN: 15m JWT_REFRESH_EXPIRES_IN: 7d PORT: "3001" FRONTEND_ORIGIN: http://localhost:3000 DOCUMENTS_STORAGE_PATH: ./test-uploads defaults: run: working-directory: ApiCore-Backend steps: - name: Checkout uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4 - name: Node einrichten uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 with: node-version: 22 - name: Datenbank-Host ermitteln und Testumgebung erzeugen # jest-e2e.json laedt .env.test per dotenv, das vorhandene Variablen # nicht ueberschreibt: alles kommt aus der Job-Umgebung, .env.test # existiert in CI nicht (gitignored). Die JWT-Secrets sind frisch # erzeugte Wegwerfwerte (mind. 32 Zeichen, voneinander verschieden), # nie echte Secrets. run: | set -eu host="" for candidate in postgres localhost; do if node -e "const s=require('net').connect(5432,process.argv[1]);s.on('connect',()=>process.exit(0));s.on('error',()=>process.exit(1));setTimeout(()=>process.exit(1),3000)" "$candidate"; then host="$candidate" break fi done if [ -z "$host" ]; then echo "Postgres weder unter 'postgres' noch unter 'localhost' erreichbar" >&2 exit 1 fi echo "Postgres-Host: $host" access="$(openssl rand -hex 32)" refresh="$(openssl rand -hex 32)" echo "::add-mask::$access" echo "::add-mask::$refresh" { echo "DATABASE_URL=postgresql://apicore:apicore-ci-only@${host}:5432/apicore_test?schema=public" echo "JWT_ACCESS_SECRET=$access" echo "JWT_REFRESH_SECRET=$refresh" } >> "$GITEA_ENV" - name: Abhaengigkeiten installieren run: npm ci - name: Prisma-Client erzeugen run: npx prisma generate - name: Migrationen anwenden # Die Rollen (z. B. BEEKEEPER) kommen aus den Migrationen, ein Seed # ist fuer die e2e-Tests nicht noetig. run: npx prisma migrate deploy - name: E2E-Tests # Auf dem geteilten Runner brauchten App-Start plus bcrypt-Logins in # beforeAll mehr als die lokalen 20 s (Laeufe 826, 836); hier 60 s. run: npm run test:e2e -- --ci --testTimeout=60000