name: CI # Runs on every push and pull request. Forks get no secrets: `pull_request` # (not `pull_request_target`) checks out the contributor's code without # access to repository secrets, which is what keeps a malicious pull request # from exfiltrating them. on: push: branches: [main, develop] pull_request: permissions: contents: read concurrency: # A new push supersedes an in-flight run on the same ref. group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true jobs: backend: name: Backend (lint + tests) runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-python@v5 with: python-version: "3.12" cache: pip - name: Install run: pip install -e ".[dev]" - name: Lint run: ruff check src/ tests/ - name: Test # Tests mock every external service, so no database or API keys. run: pytest -q frontend: name: Frontend (typecheck + tests) runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: "20" cache: npm cache-dependency-path: frontend/package-lock.json - name: Install working-directory: frontend run: npm ci - name: Typecheck working-directory: frontend run: npx tsc --noEmit - name: Test working-directory: frontend run: npm test migrations: name: Migrations apply cleanly runs-on: ubuntu-latest services: postgres: image: pgvector/pgvector:pg16 env: POSTGRES_DB: numen POSTGRES_USER: postgres POSTGRES_PASSWORD: password ports: ["5432:5432"] options: >- --health-cmd "pg_isready -U postgres" --health-interval 5s --health-timeout 5s --health-retries 10 steps: - uses: actions/checkout@v4 - uses: actions/setup-python@v5 with: python-version: "3.12" cache: pip - name: Install run: pip install -e ".[dev]" - name: Upgrade to head # Catches a broken chain, and that the RLS migration works against a # database whose name and role password come from the environment. env: DATABASE_URL: postgresql+asyncpg://postgres:password@localhost:5432/numen NUMEN_APP_PASSWORD: ci_app_password run: alembic upgrade head