name: Test Suite on: push: branches: [main, develop] workflow_run: workflows: ["Deploy Development", "Deploy Production"] types: [completed] jobs: lint-backend: if: ${{ github.event_name != 'workflow_run' || github.event.workflow_run.conclusion == 'success' }} runs-on: ubuntu-latest steps: - name: Check backend syntax run: | EVENT_NAME="${{ github.event_name }}" REF_NAME="${{ github.ref_name }}" RUN_WORKFLOW="${{ github.event.workflow_run.name }}" APP_DIR="/home/lars/docker/shinkan" if [ "$EVENT_NAME" = "workflow_run" ]; then if [ "$RUN_WORKFLOW" = "Deploy Development" ]; then APP_DIR="/home/lars/docker/shinkan-dev" fi elif [ "$REF_NAME" = "develop" ]; then APP_DIR="/home/lars/docker/shinkan-dev" fi python3 -m py_compile "$APP_DIR/backend/main.py" echo "✓ Backend syntax OK" build-frontend: if: ${{ github.event_name != 'workflow_run' || github.event.workflow_run.conclusion == 'success' }} runs-on: ubuntu-latest steps: - name: Build frontend run: | EVENT_NAME="${{ github.event_name }}" REF_NAME="${{ github.ref_name }}" RUN_WORKFLOW="${{ github.event.workflow_run.name }}" APP_DIR="/home/lars/docker/shinkan" if [ "$EVENT_NAME" = "workflow_run" ]; then if [ "$RUN_WORKFLOW" = "Deploy Development" ]; then APP_DIR="/home/lars/docker/shinkan-dev" fi elif [ "$REF_NAME" = "develop" ]; then APP_DIR="/home/lars/docker/shinkan-dev" fi cd "$APP_DIR/frontend" npm install npm run build echo "✓ Frontend build OK" playwright-tests: if: ${{ github.event_name != 'workflow_run' || github.event.workflow_run.conclusion == 'success' }} runs-on: ubuntu-latest # Kein zusätzlicher docker-compose im Job: keine zweiten Container/Host-Ports. # Dev: Tests gegen bereits deployte URL (HTTPS, Reverse-Proxy). Prod: gleicher Ablauf. env: # Öffentliche Dev-Basis — muss ALLOWED_ORIGINS / Nginx entsprechen; bei anderer Domain Workflow anpassen. E2E_TARGET_URL: https://dev.shinkan.jinkendo.de steps: - name: Checkout repository uses: actions/checkout@v4 - name: Setup Node.js uses: actions/setup-node@v4 with: node-version: '20' - 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 "→ Prod. Secrets: E2E_PROD_TEST_EMAIL / E2E_PROD_TEST_PASSWORD." else echo "mode=dev" >> $GITHUB_OUTPUT echo "base_url=${DEV_BASE}" >> $GITHUB_OUTPUT echo "→ Deployte Dev-Umgebung (${DEV_BASE}). Secrets: E2E_DEV_TEST_EMAIL / E2E_DEV_TEST_PASSWORD." 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: Testnutzer registrieren (Dev, nur wenn möglich) if: ${{ steps.e2e.outputs.mode == 'dev' }} env: E2E_DEV_TEST_EMAIL: ${{ secrets.E2E_DEV_TEST_EMAIL }} E2E_DEV_TEST_PASSWORD: ${{ secrets.E2E_DEV_TEST_PASSWORD }} run: | BASE="${{ steps.e2e.outputs.base_url }}" if [ -z "$E2E_DEV_TEST_EMAIL" ] || [ -z "$E2E_DEV_TEST_PASSWORD" ]; then echo "(Registrierung übersprungen — Secrets E2E_DEV_* nicht gesetzt.)" exit 0 fi curl -sf -X POST "$BASE/api/auth/register" \ -H "Content-Type: application/json" \ -d "{\"email\":\"${E2E_DEV_TEST_EMAIL}\",\"password\":\"${E2E_DEV_TEST_PASSWORD}\",\"name\":\"Playwright CI\"}" \ || echo "(Register evtl. schon erfolgt oder Limits — Login-Test gilt trotzdem.)" - name: Install Playwright run: | npm ci || npm install npx playwright install --with-deps chromium - name: Run Playwright tests env: E2E_DEV_TEST_EMAIL: ${{ secrets.E2E_DEV_TEST_EMAIL }} E2E_DEV_TEST_PASSWORD: ${{ secrets.E2E_DEV_TEST_PASSWORD }} run: | set -e MODE="${{ steps.e2e.outputs.mode }}" BASE_URL="${{ steps.e2e.outputs.base_url }}" export PLAYWRIGHT_BASE_URL="$BASE_URL" if [ "$MODE" = "prod" ]; then export TEST_EMAIL="${{ secrets.E2E_PROD_TEST_EMAIL }}" export TEST_PASSWORD="${{ secrets.E2E_PROD_TEST_PASSWORD }}" if [ -z "$TEST_EMAIL" ] || [ -z "$TEST_PASSWORD" ]; then echo "Fehler: E2E_PROD_TEST_EMAIL und E2E_PROD_TEST_PASSWORD setzen." exit 1 fi else export TEST_EMAIL="$E2E_DEV_TEST_EMAIL" export TEST_PASSWORD="$E2E_DEV_TEST_PASSWORD" if [ -z "$TEST_EMAIL" ] || [ -z "$TEST_PASSWORD" ]; then echo "Fehler: E2E_DEV_TEST_EMAIL und E2E_DEV_TEST_PASSWORD setzen (Playwright soll gegen Dev einloggen)." exit 1 fi fi mkdir -p screenshots npx playwright test echo "✓ Playwright tests passed" - name: Upload test screenshots if: failure() uses: actions/upload-artifact@v4 with: name: playwright-screenshots path: screenshots/ retention-days: 7