name: CI on: push: branches: [main] pull_request: branches: [main] jobs: backend: runs-on: ubuntu-latest services: postgres: image: postgres:16 env: POSTGRES_USER: postgres POSTGRES_PASSWORD: postgres POSTGRES_DB: patherly_test ports: - 5432:5432 options: >- --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5 env: DATABASE_URL: postgresql+asyncpg://postgres:postgres@localhost:5432/patherly_test DATABASE_URL_SYNC: postgresql://postgres:postgres@localhost:5432/patherly_test SECRET_KEY: ci-test-secret-key-not-for-production DEBUG: "true" APP_NAME: ResolutionFlow steps: - uses: actions/checkout@v4 - name: Set up Python 3.11 uses: actions/setup-python@v5 with: python-version: "3.11" cache: pip cache-dependency-path: | backend/requirements.txt backend/requirements-dev.txt - name: Install dependencies run: pip install -r backend/requirements.txt -r backend/requirements-dev.txt - name: Run tests with coverage run: cd backend && python -m pytest --override-ini="addopts=" --cov=app --cov-report=term-missing --cov-report=json:coverage.json - name: Display coverage summary if: always() run: | cd backend python -c " import json with open('coverage.json') as f: data = json.load(f) total = data['totals']['percent_covered_display'] print(f'Total coverage: {total}%') print() print('Module coverage:') for fname, fdata in sorted(data['files'].items()): pct = fdata['summary']['percent_covered_display'] if float(pct) < 80: print(f' ⚠ {fname}: {pct}%') else: print(f' ✓ {fname}: {pct}%') " frontend: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Set up Node.js 20 uses: actions/setup-node@v4 with: node-version: "20" cache: npm cache-dependency-path: frontend/package-lock.json - name: Install dependencies run: cd frontend && npm ci - name: Lint run: cd frontend && npm run lint - name: Test run: cd frontend && npm test - name: Build run: cd frontend && npm run build e2e: runs-on: ubuntu-latest services: postgres: image: postgres:16 env: POSTGRES_USER: postgres POSTGRES_PASSWORD: postgres POSTGRES_DB: patherly_test ports: - 5432:5432 options: >- --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5 env: PLAYWRIGHT_DATABASE_URL: postgresql+asyncpg://postgres:postgres@127.0.0.1:5432/patherly_test PLAYWRIGHT_DATABASE_URL_SYNC: postgresql://postgres:postgres@127.0.0.1:5432/patherly_test PLAYWRIGHT_API_ORIGIN: http://127.0.0.1:8000 PLAYWRIGHT_BASE_URL: http://127.0.0.1:4173 PLAYWRIGHT_SECRET_KEY: ci-playwright-secret-key PLAYWRIGHT_TEST_EMAIL: teamadmin@resolutionflow.example.com PLAYWRIGHT_TEST_PASSWORD: TestPass123! steps: - uses: actions/checkout@v4 - name: Set up Python 3.11 uses: actions/setup-python@v5 with: python-version: "3.11" cache: pip cache-dependency-path: | backend/requirements.txt backend/requirements-dev.txt - name: Set up Node.js 20 uses: actions/setup-node@v4 with: node-version: "20" cache: npm cache-dependency-path: frontend/package-lock.json - name: Install backend dependencies run: pip install -r backend/requirements.txt -r backend/requirements-dev.txt - name: Install frontend dependencies run: cd frontend && npm ci - name: Install Playwright browser run: cd frontend && npx playwright install --with-deps chromium - name: Run Playwright smoke tests run: cd frontend && npm run test:e2e - name: Upload Playwright report if: always() uses: actions/upload-artifact@v4 with: name: playwright-report path: | frontend/playwright-report frontend/test-results if-no-files-found: ignore