diff --git a/.gitea/workflows/ci.yml b/.gitea/workflows/ci.yml new file mode 100644 index 00000000..2bc952b5 --- /dev/null +++ b/.gitea/workflows/ci.yml @@ -0,0 +1,154 @@ +name: CI + +on: + push: + branches: [main] + pull_request: + branches: [main] + +jobs: + backend: + runs-on: ubuntu-latest + + services: + postgres: + image: pgvector/pgvector:pg16 + env: + POSTGRES_USER: postgres + POSTGRES_PASSWORD: postgres + POSTGRES_DB: resolutionflow_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/resolutionflow_test + DATABASE_URL_SYNC: postgresql://postgres:postgres@localhost:5432/resolutionflow_test + SECRET_KEY: ci-test-secret-key-not-for-production + DEBUG: "true" + APP_NAME: ResolutionFlow + TEST_DB_NAME: resolutionflow_test + DB_APP_ROLE_PASSWORD: app_secret_ci + + steps: + - uses: actions/checkout@v4 + + - name: Install dependencies + run: pip install -r backend/requirements.txt -r backend/requirements-dev.txt + + - name: Run Alembic migrations + run: cd backend && alembic upgrade head + + - name: Check tenant filter enforcement + run: cd backend && python scripts/check_tenant_filters.py + + - 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 --cov-fail-under=50 + + - 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' WARNING {fname}: {pct}%') + else: + print(f' OK {fname}: {pct}%') + " + + frontend: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - name: Install dependencies + run: cd frontend && npm ci + + - name: Lint + run: cd frontend && npm run lint + + - name: Test with coverage + run: cd frontend && npm run test:coverage + + - name: Build + run: cd frontend && NODE_OPTIONS="--max-old-space-size=4096" npm run build + + - name: Upload build artifact + uses: actions/upload-artifact@v4 + with: + name: frontend-dist + path: frontend/dist + retention-days: 1 + + e2e: + needs: [frontend] + runs-on: ubuntu-latest + + services: + postgres: + image: pgvector/pgvector:pg16 + env: + POSTGRES_USER: postgres + POSTGRES_PASSWORD: postgres + POSTGRES_DB: resolutionflow_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/resolutionflow_test + PLAYWRIGHT_DATABASE_URL_SYNC: postgresql://postgres:postgres@127.0.0.1:5432/resolutionflow_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: 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: Download frontend build + uses: actions/download-artifact@v4 + with: + name: frontend-dist + path: frontend/dist + + - 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