name: CI/CD

# Gitea Actions pipeline for the UMP / ImageHub monorepo.
#   backend  — be0 (FastAPI, Python 3.11) pytest against a throwaway Postgres
#   frontend — npm workspaces (shared + 4 Vite/React SPAs): typecheck, build, unit tests
#   deploy   — on push to main only: build + `docker compose up -d` on the host runner
#
# Runner labels expected (act_runner registered on 103.149.170.102):
#   ci      -> docker mode (clean, ephemeral)   used by backend + frontend
#   deploy  -> host mode  (drives host docker)  used by deploy
on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  backend:
    runs-on: ci
    services:
      postgres:
        image: postgres:16-alpine
        env:
          POSTGRES_USER: initiative
          POSTGRES_PASSWORD: initiative_secret
          POSTGRES_DB: initiatives
        ports:
          - 5432:5432
        options: >-
          --health-cmd "pg_isready -U initiative -d initiatives"
          --health-interval 5s --health-timeout 5s --health-retries 10
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with:
          python-version: "3.11"
      - name: Install backend deps (+ test deps)
        working-directory: be0
        run: |
          python -m pip install --upgrade pip
          pip install -r requirements-dev.txt
      - name: Unit tests — pytest PER FILE (isolates asyncpg event loop per module)
        working-directory: be0
        env:
          INITIATIVE_DATABASE_URL: postgresql+asyncpg://initiative:initiative_secret@postgres:5432/initiatives
          # S3Settings has 6 required fields — the app won't import without them
          # (tests don't hit real MinIO; dummy values just satisfy validation).
          S3_ENDPOINT_URL: http://localhost:9000
          S3_ACCESS_KEY: testkey
          S3_SECRET_KEY: testsecret
          S3_BUCKET_ATTACHMENTS: initiative-attachments
          S3_BUCKET_EXPORTS: initiative-exports
          S3_BUCKET_QUARANTINE: initiative-quarantine
          JWT_SECRET: ci_test_jwt_secret_at_least_32_characters_long
        run: |
          set -e
          fail=0
          for f in tests/test_*.py; do
            echo "::group::$f"
            python -m pytest "$f" -q || fail=1
            echo "::endgroup::"
          done
          exit $fail

  frontend:
    runs-on: ci
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: "20"
      - name: Install (workspaces)
        run: npm ci
      - name: Typecheck (all workspaces)
        run: npm run typecheck
      - name: Build (all workspaces)
        run: npm run build
      - name: Unit tests (workspaces w/ vitest — shared, investigator, publisher)
        run: npm test --workspaces --if-present

  # Deploy runs in HOST mode from a PERSISTENT dir (NOT the ephemeral runner
  # workspace): docker-compose.prod.yml bind-mounts ./assets/minio-data and
  # ./be0, so MinIO data + submitted files must live on a stable host path or
  # they would be wiped on every deploy.
  # NOTE: intentionally NOT gated on backend/frontend success — the deploy must
  # ship on push to main even while the test suite is still being tuned. Re-add
  # `needs: [backend, frontend]` once the gates are green to make tests blocking.
  deploy:
    if: github.event_name == 'push' && github.ref == 'refs/heads/main'
    runs-on: deploy
    steps:
      - name: Sync code to persistent deploy dir
        run: |
          set -euo pipefail
          DEPLOY_DIR=/srv/sciagent
          if [ ! -d "$DEPLOY_DIR/.git" ]; then
            git clone http://localhost:3000/tlam89/sciagent.git "$DEPLOY_DIR"
          fi
          cd "$DEPLOY_DIR"
          git fetch origin main
          git reset --hard origin/main
      - name: Materialize prod .env from secret
        run: |
          set -euo pipefail
          printf '%s' "${{ secrets.PROD_ENV }}" > /srv/sciagent/.env
          chmod 600 /srv/sciagent/.env
      - name: Deploy stack (build locally, no registry pull)
        run: cd /srv/sciagent && bash scripts/deploy-prod.sh --no-pull
      - name: Stack health check
        run: cd /srv/sciagent && bash scripts/check-prod-stack.sh
