name: CI on: push: branches: [main, develop] pull_request: jobs: # --------------------------------------------------------------------------- # Backend: ruff lint + pytest with coverage gate (rises as junior tests land) # --------------------------------------------------------------------------- backend: name: Backend (Python) runs-on: ubuntu-latest defaults: run: working-directory: backend steps: - uses: actions/checkout@v4 - uses: astral-sh/setup-uv@v5 with: version: "latest" - name: Install dependencies run: uv sync - name: Lint (ruff) run: uv run ruff check . - name: Format check (ruff) run: uv run ruff format --check . - name: Test with coverage # Measured ~81%; set threshold 1-2pp below to catch regressions. run: uv run pytest --cov=app --cov-report=term-missing --cov-fail-under=80 # --------------------------------------------------------------------------- # Frontend: ESLint + Vitest with 90% coverage gate # --------------------------------------------------------------------------- frontend: name: Frontend (TypeScript) runs-on: ubuntu-latest defaults: run: working-directory: frontend 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 dependencies run: npm ci - name: Type check run: npm run typecheck - name: Lint run: npm run lint - name: Test with coverage run: npm run coverage # --------------------------------------------------------------------------- # E2E (Playwright): browser-driven checks the unit suites can't catch — # see frontend/e2e/ for what each spec guards against. NOT a required/ # blocking gate yet (continue-on-error): it should run and report for a # while before it can fail anyone's merge. Promoting it: drop # `continue-on-error`, add this job to the branch protection's required # checks, and confirm several consecutive green runs first. # --------------------------------------------------------------------------- e2e: name: E2E (Playwright) runs-on: ubuntu-latest continue-on-error: true steps: - uses: actions/checkout@v4 - uses: astral-sh/setup-uv@v5 with: version: "latest" - uses: actions/setup-node@v4 with: node-version: "20" - name: Install backend dependencies working-directory: backend run: uv sync - name: Install frontend dependencies working-directory: frontend run: npm install - name: Install Playwright browsers working-directory: frontend run: npx playwright install --with-deps chromium - name: Run Playwright E2E suite working-directory: frontend run: npm run e2e - name: Upload Playwright report if: always() uses: actions/upload-artifact@v4 with: name: playwright-report path: frontend/playwright-report/ retention-days: 7