name: EK-DOS-WEB bauen und ausrollen

on:
  push:
    branches: [main]
  workflow_dispatch:

env:
  DEPLOY_HOST: 10.0.11.131
  DEPLOY_USER: deploy
  DEPLOY_ROOT: /var/www/ekdos

jobs:
  # ──────────────────────────────────────────────────────────────────────────
  # Die Oberfläche wird hier zu statischen Dateien kompiliert. Node existiert
  # ausschliesslich in diesem Container; auf dem Zielserver läuft keines.
  # ──────────────────────────────────────────────────────────────────────────
  frontend:
    runs-on: ubuntu-latest
    container: node:22-bookworm-slim
    defaults:
      run:
        working-directory: frontend
    steps:
      - uses: actions/checkout@v4

      - name: pnpm bereitstellen
        run: corepack enable && corepack prepare pnpm@10.16.1 --activate

      - name: Abhängigkeiten installieren
        run: pnpm install --frozen-lockfile

      # Typprüfung getrennt, damit ein Typfehler nicht als Bündelfehler erscheint.
      - name: Typen prüfen
        run: pnpm typecheck

      - name: Bündel bauen
        run: pnpm build

      - uses: actions/upload-artifact@v3
        with:
          name: frontend-dist
          path: frontend/dist
          retention-days: 7

  # ──────────────────────────────────────────────────────────────────────────
  # Das Backend wird nicht kompiliert, aber geprüft: Syntax aller Dateien und
  # ein Abhängigkeitsbaum ohne Entwicklungspakete.
  # ──────────────────────────────────────────────────────────────────────────
  backend:
    runs-on: ubuntu-latest
    container: php:8.5-cli
    defaults:
      run:
        working-directory: backend
    steps:
      - uses: actions/checkout@v4

      - name: Composer und Erweiterungen bereitstellen
        run: |
          apt-get update && apt-get install -y --no-install-recommends git unzip libpq-dev
          docker-php-ext-install pdo_pgsql
          curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer

      - name: Abhängigkeiten installieren
        run: composer install --no-dev --no-interaction --prefer-dist --optimize-autoloader --ignore-platform-req=ext-redis

      - name: Syntax prüfen
        run: find src public bin -type f \( -name '*.php' -o -name 'ekdos' \) -print0 | xargs -0 -n1 php -l

      - uses: actions/upload-artifact@v3
        with:
          name: backend-build
          path: |
            backend
            !backend/.env
          retention-days: 7

  # ──────────────────────────────────────────────────────────────────────────
  # Ausrollen. Jede Veröffentlichung landet in einem eigenen Verzeichnis; erst
  # der Symlink-Tausch macht sie sichtbar. Ein Fehlschlag lässt die laufende
  # Fassung unberührt.
  # ──────────────────────────────────────────────────────────────────────────
  deploy:
    runs-on: ubuntu-latest
    needs: [frontend, backend]
    if: gitea.ref == 'refs/heads/main'
    steps:
      - uses: actions/download-artifact@v3
        with:
          name: frontend-dist
          path: dist

      - uses: actions/download-artifact@v3
        with:
          name: backend-build
          path: backend

      - name: SSH einrichten
        run: |
          install -m 700 -d ~/.ssh
          echo "${{ secrets.DEPLOY_SSH_KEY }}" > ~/.ssh/id_ed25519
          chmod 600 ~/.ssh/id_ed25519
          ssh-keyscan -H "$DEPLOY_HOST" >> ~/.ssh/known_hosts

      - name: Oberfläche übertragen
        run: |
          RELEASE="$DEPLOY_ROOT/releases/${{ gitea.sha }}"
          ssh "$DEPLOY_USER@$DEPLOY_HOST" "mkdir -p '$RELEASE'"
          rsync -az --delete dist/ "$DEPLOY_USER@$DEPLOY_HOST:$RELEASE/"

      - name: Backend übertragen
        run: |
          # .env bleibt auf dem Server und wird nie überschrieben.
          rsync -az --delete \
            --exclude '.env' \
            --exclude 'var/cache' \
            backend/ "$DEPLOY_USER@$DEPLOY_HOST:$DEPLOY_ROOT/backend/"

      - name: Umschalten und neu laden
        run: |
          ssh "$DEPLOY_USER@$DEPLOY_HOST" bash -euo pipefail <<'REMOTE'
            cd /var/www/ekdos

            # Schema fortschreiben, bevor die neue Oberfläche sichtbar wird.
            php backend/bin/ekdos migrate

            # Atomarer Tausch: ln -sfn auf ein temporäres Ziel, dann umbenennen.
            ln -sfn "releases/${GITEA_SHA:-$(ls -1t releases | head -1)}" current.new
            mv -Tf current.new current

            # Opcache hält den alten Quelltext, bis fpm neu lädt.
            sudo systemctl reload php8.5-fpm

            # Zwischengespeicherte n8n-Antworten passen womöglich nicht mehr
            # zum neuen Abbildungscode.
            php backend/bin/ekdos cache:flush

            # Die letzten fünf Veröffentlichungen behalten.
            ls -1t releases | tail -n +6 | xargs -r -I{} rm -rf "releases/{}"
          REMOTE
        env:
          GITEA_SHA: ${{ gitea.sha }}

      - name: Gesundheitsprüfung
        run: |
          ssh "$DEPLOY_USER@$DEPLOY_HOST" \
            'curl -fsS -o /dev/null -w "%{http_code}\n" http://127.0.0.1/api/health'
