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 # Lokal: docker-compose.dev-env + COMPOSE_PROJECT_NAME. Nach „Deploy Production“: HTTPS-Prod (kein Docker). env: COMPOSE_PROJECT_NAME: shinkan-e2e-${{ github.run_id }} 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 (lokal vs. Production) id: e2e run: | EVENT="${{ github.event_name }}" WF_NAME="${{ github.event.workflow_run.name }}" if [ "$EVENT" = "workflow_run" ] && [ "$WF_NAME" = "Deploy Production" ]; then echo "mode=prod" >> $GITHUB_OUTPUT echo "base_url=https://shinkan.jinkendo.de" >> $GITHUB_OUTPUT echo "→ Playwright gegen Production. Login: Secrets E2E_PROD_TEST_EMAIL / E2E_PROD_TEST_PASSWORD." else echo "mode=local" >> $GITHUB_OUTPUT echo "base_url=http://127.0.0.1:3098" >> $GITHUB_OUTPUT echo "→ Playwright gegen lokalen Stack (docker-compose.dev-env.yml)." fi - name: Start dev stack for E2E (nur lokal) if: ${{ steps.e2e.outputs.mode == 'local' }} env: DEV_ALLOWED_ORIGINS: http://127.0.0.1:3098,http://localhost:3098,http://host.docker.internal:3098,https://dev.shinkan.jinkendo.de run: | docker compose -f docker-compose.dev-env.yml up -d --build echo "Warte auf Frontend + API (/health) …" for i in $(seq 1 90); do if curl -sf http://127.0.0.1:3098/health >/dev/null 2>&1; then echo "Health OK (Versuch $i)" exit 0 fi sleep 2 done echo "Timeout: /health nicht erreichbar" curl -v http://127.0.0.1:3098/health || true docker compose -f docker-compose.dev-env.yml logs --tail=120 exit 1 - name: Prod /health abwarten (nach Deploy) 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: Seed E2E-User (nur lokaler Stack, frische DB) if: ${{ steps.e2e.outputs.mode == 'local' }} env: TEST_EMAIL: lars@stommer.com TEST_PASSWORD: 12345678 run: | curl -sf -X POST "http://127.0.0.1:3098/api/auth/register" \ -H "Content-Type: application/json" \ -d "{\"email\":\"${TEST_EMAIL}\",\"password\":\"${TEST_PASSWORD}\",\"name\":\"Playwright CI\"}" \ || echo "(Registrierung übersprungen — Nutzer existiert evtl. schon)" - name: Install Playwright run: | npm ci || npm install npx playwright install --with-deps chromium - name: Run Playwright tests run: | set -e MODE="${{ steps.e2e.outputs.mode }}" BASE_URL="${{ steps.e2e.outputs.base_url }}" if [ "$MODE" = "prod" ]; then export PLAYWRIGHT_BASE_URL="$BASE_URL" 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: Für Prod-E2E Repository-Secrets E2E_PROD_TEST_EMAIL und E2E_PROD_TEST_PASSWORD setzen (Testnutzer mit Login auf Prod)." exit 1 fi else export PLAYWRIGHT_BASE_URL="$BASE_URL" export TEST_EMAIL="lars@stommer.com" export TEST_PASSWORD="12345678" fi mkdir -p screenshots npx playwright test echo "✓ Playwright tests passed" - name: Stop dev stack if: ${{ always() && steps.e2e.outputs.mode == 'local' }} run: | docker compose -f docker-compose.dev-env.yml down --remove-orphans echo "Gestoppt unter Projekt: ${COMPOSE_PROJECT_NAME}" - name: Upload test screenshots if: failure() uses: actions/upload-artifact@v4 with: name: playwright-screenshots path: screenshots/ retention-days: 7