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 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. deploy: needs: [backend, frontend] 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