name: CI on: push: branches: [main] pull_request: branches: [main] jobs: backend: name: Backend (lint + tests + compose) runs-on: ubuntu-latest steps: - uses: actions/checkout@v5 - uses: actions/setup-python@v6 with: python-version: "3.11" cache: "pip" - name: Install (light deps only, skip ocrmypdf/docling/torch) run: | python -m pip install --upgrade pip pip install \ "pydantic>=2.7" "pydantic-settings>=2.4" \ "sqlalchemy>=2.0.30" "psycopg[binary]>=3.2" \ "alembic>=1.13" "minio>=7.2.7" \ "opensearch-py>=2.6" "qdrant-client>=1.10" \ "celery>=5.4" "redis>=5.0" \ "fastapi>=0.115" "uvicorn[standard]>=0.30" \ "structlog>=24.2" "tenacity>=8.5" "langdetect>=1.0.9" \ "regex>=2024.5.15" "click>=8.1.7" \ "pytest>=8.2" "pytest-asyncio>=0.23" \ ruff - name: Install document recognition engine (pinned tag, needs ENGINES_TOKEN) # The engine repo is private; ENGINES_TOKEN is a PAT with read access # to GoodOneFather/TeamHUB_Engines. --no-deps keeps CI light: docling # and ocrmypdf are imported lazily inside engine functions, only # pdfminer.six is needed at import time. Pin must match # app/ingestion/ENGINE_SOURCE.md. env: ENGINES_TOKEN: ${{ secrets.ENGINES_TOKEN }} run: | if [ -z "$ENGINES_TOKEN" ]; then echo "::error::ENGINES_TOKEN secret is not available to Actions (repo Settings -> Secrets and variables -> Actions)" exit 1 fi git config --global url."https://x-access-token:${ENGINES_TOKEN}@github.com/".insteadOf "https://github.com/" pip install "pdfminer.six>=20240706" pip install --no-deps \ "teamhub-document-recognition-engine @ git+https://github.com/GoodOneFather/TeamHUB_Engines.git@teamhub-document-recognition-engine-v0.1.0#subdirectory=engines/teamhub-document-recognition-engine" - name: Ruff run: ruff check app scripts tests - name: Compile run: python -m compileall -q app scripts tests - name: Module size report (report-only guardrail) run: python scripts/report_module_sizes.py - name: Pytest (unit only — heavy deps excluded) # The pinned engine is installed above, so test_chunker.py and the # engine adapter tests run for real here; -rs surfaces any skips. run: | pytest tests/test_hashing.py tests/test_quality.py \ tests/test_chunker.py tests/test_duplicates.py \ tests/test_document_recognition_engine_adapter.py \ tests/test_hybrid_search.py -q -rs - name: docker compose config run: docker compose config --quiet - name: docker compose config (prod overlay) run: | test -f docker-compose.prod.yml && \ docker compose --env-file .env.prod.example \ -f docker-compose.yml -f docker-compose.prod.yml config --quiet || \ echo "prod overlay absent, skipping" frontend: name: Frontend (lint + type-check + build) runs-on: ubuntu-latest defaults: run: working-directory: frontend steps: - uses: actions/checkout@v5 - uses: actions/setup-node@v5 with: node-version: "20" cache: "npm" cache-dependency-path: frontend/package-lock.json - run: npm ci - name: ESLint run: npm run lint - name: TypeScript run: npx tsc --noEmit - name: Build run: npx vite build