# CI плеера Рублокса.
# Запускается на каждый push и pull_request.
#
# Что проверяем:
#   1. lint — ESLint без warning'ов
#   2. format-check — Prettier формат не нарушен
#   3. build — vite build проходит без ошибок
#   4. secret-scan — trufflehog не нашёл утечек секретов
#   5. size-check — PR не больше 1000 строк (предупреждение)
name: CI

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  lint:
    name: Lint
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: '18'
      - run: npm ci
      # format:check временно отключён до массового npx prettier --write
      # (см. docs/ONBOARDING.md → «Форматирование кода»). После прогона
      # верни строку `- run: npm run format:check` перед npm run lint.
      - run: npm run lint

  build:
    name: Build
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: '18'
      - run: npm ci
      - run: npm run build
      - name: Save build size
        # set -o pipefail (default Gitea Actions) валит step при SIGPIPE
        # от head. Делаем команды непадающими через || true.
        run: |
          du -sh build/ || true
          ls -la build/assets/ 2>/dev/null | head -10 || true

  secret-scan:
    name: Secret scan
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
        with:
          fetch-depth: 0
      - name: Install trufflehog
        run: |
          curl -sSfL https://raw.githubusercontent.com/trufflesecurity/trufflehog/main/scripts/install.sh \
            | sh -s -- -b /usr/local/bin
      - name: Run trufflehog
        run: |
          trufflehog git "file://$(pwd)" \
            --only-verified --fail \
            --exclude-paths .trufflehog-ignore 2>&1 | tee scan.log || EXIT=$?
          if [ -n "$EXIT" ] && [ "$EXIT" -ne 0 ]; then
            echo "::error::Найдены секреты в коммитах! См. лог выше."
            exit 1
          fi

  size-check:
    name: PR size check
    if: github.event_name == 'pull_request'
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
        with:
          fetch-depth: 0
      - name: Check PR size
        run: |
          ADDED=$(git diff origin/${{ github.base_ref }}...HEAD --shortstat | grep -oE '[0-9]+ insertion' | grep -oE '[0-9]+' || echo 0)
          REMOVED=$(git diff origin/${{ github.base_ref }}...HEAD --shortstat | grep -oE '[0-9]+ deletion' | grep -oE '[0-9]+' || echo 0)
          TOTAL=$((ADDED + REMOVED))
          echo "PR изменяет $TOTAL строк (+$ADDED / -$REMOVED)"
          if [ "$TOTAL" -gt 1000 ]; then
            echo "::warning::PR изменяет $TOTAL строк (> 1000). Подумай о дроблении на несколько меньших."
          fi

  # ────────────────────────────────────────────────────────────────────
  # DEPLOY — собирает прод-бандл и заливает на ОБА сервера (S1+S2)
  # параллельно через rsync over SSH.
  #
  # Запускается ТОЛЬКО на push в main (т.е. после успешного мержа PR).
  # PR-проверки выше (lint/build/secret-scan/size-check) гарантируют
  # что в main попадает только корректный код.
  #
  # Секреты:
  #   DEPLOY_SSH_KEY  — приватный ed25519 ключ (CI-only, отдельный от
  #                      админских), pubkey уже на ~min/.ssh/authorized_keys
  #                      на S1 VM 124 и S2 VM 124
  #   KNOWN_HOSTS     — host-keys S1 и S2 (защита от MITM)
  #
  # Цели (на VM 124 обоих серверов):
  #   /var/www/rublox-player/build/
  # ────────────────────────────────────────────────────────────────────
  deploy:
    name: Deploy to S1 + S2
    if: github.event_name == 'push' && github.ref == 'refs/heads/main'
    # Lint НЕ в needs — он опциональный (исторический долг empty-блоков
    # ещё не вычищен, см. branch protection без 'CI / Lint' в required).
    # Deploy всё равно зависит от Build и Secret-scan — это критично.
    needs: [build, secret-scan]
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: '18'
      - name: Install deps
        run: npm ci
      - name: Production build
        run: npm run build
      - name: Prepare SSH
        env:
          DEPLOY_SSH_KEY: ${{ secrets.DEPLOY_SSH_KEY }}
          KNOWN_HOSTS: ${{ secrets.KNOWN_HOSTS }}
        run: |
          mkdir -p ~/.ssh && chmod 700 ~/.ssh
          echo "$DEPLOY_SSH_KEY" > ~/.ssh/id_deploy
          chmod 600 ~/.ssh/id_deploy
          echo "$KNOWN_HOSTS" > ~/.ssh/known_hosts
          chmod 600 ~/.ssh/known_hosts
      - name: Install rsync
        run: apt-get update -qq && apt-get install -y rsync openssh-client
      # S1 — НЕ блокирующий: при недоступности S1 (downtime) деплой не должен
      # валиться, главное доставить на S2. ConnectTimeout 20с чтобы не висеть.
      - name: Deploy to S1 (85.175.7.40:1998)
        continue-on-error: true
        run: |
          rsync -az --delete-after --human-readable --exclude=wiki --exclude=kubikon-assets \
            -e "ssh -i ~/.ssh/id_deploy -o UserKnownHostsFile=~/.ssh/known_hosts -o ConnectTimeout=20 -p 1998" \
            build/ min@85.175.7.40:/var/www/rublox-player/build/
      - name: Deploy to S2 (192.168.0.124:22, runner в той же сети)
        run: |
          rsync -az --delete-after --human-readable --exclude=wiki --exclude=kubikon-assets \
            -e "ssh -i ~/.ssh/id_deploy -o UserKnownHostsFile=~/.ssh/known_hosts -p 22" \
            build/ min@192.168.0.124:/var/www/rublox-player/build/
      - name: Verify S1 (не блокирующий)
        continue-on-error: true
        run: |
          ssh -i ~/.ssh/id_deploy -o UserKnownHostsFile=~/.ssh/known_hosts -o ConnectTimeout=20 -p 1998 \
            min@85.175.7.40 \
            "ls /var/www/rublox-player/build/index.html && du -sh /var/www/rublox-player/build/"
      - name: Verify S2 (обязательный)
        run: |
          ssh -i ~/.ssh/id_deploy -o UserKnownHostsFile=~/.ssh/known_hosts -p 22 \
            min@192.168.0.124 \
            "ls /var/www/rublox-player/build/index.html && du -sh /var/www/rublox-player/build/"
