docs(readme): refresh to v0.7.0 (player-centric surface + 4 new endpo… #38
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # GitHub Actions: lint + type-check + test the gw2analytics monorepo. | ||
| # | ||
| # Mirrors the local pre-commit + pipeline (uv run ruff check, | ||
| # uv run ruff format --check, uv run mypy libs apps --no-incremental, | ||
| # uv run pytest) so a PR cannot regress any of these gates. | ||
| # | ||
| # pytest-env injects the docker-compose dev credentials at session | ||
| # startup, so this workflow does not need any GitHub repository | ||
| # secrets. A ``postgres`` service runs alongside the job so the | ||
| # end-to-end ``apps/api/tests/test_uploads_e2e.py::test_uploads_e2e_happy_path`` | ||
| # test can hit a real database at ``localhost:5432`` and exercise the | ||
| # full POST /api/v1/uploads -> GET /api/v1/uploads/{id} -> | ||
| # GET /api/v1/fights/{id} chain against a real Postgres schema | ||
| # (instead of silently skipping). | ||
| # | ||
| # The web/ gates (Phase 4) are split into a **drift gate** plus a | ||
| # **typecheck gate**: | ||
| # | ||
| # - Drift gate: re-dump ``app.openapi()`` (no uvicorn -- no port, | ||
| # no orphan processes, deterministic < 1 s) and feed it through | ||
| # ``openapi-typescript`` to ``web/src/lib/api/schema.d.ts``. A | ||
| # ``git diff --exit-code`` fails the build if the regenerated | ||
| # client differs from the committed baseline (i.e. the developer | ||
| # touched an endpoint without re-running ``pnpm generate:api``). | ||
| # - Typecheck gate: ``tsc --noEmit`` verifies the frontend types | ||
| # after the refresh. | ||
| name: CI | ||
| on: | ||
| push: | ||
| branches: [main] | ||
| pull_request: | ||
| branches: [main] | ||
| workflow_dispatch: | ||
| # Cancel in-progress runs on the same branch when a new commit is | ||
| # pushed to the same PR (saves CI minutes on stale branches). | ||
| concurrency: | ||
| group: ci-${{ github.ref }} | ||
| cancel-in-progress: true | ||
| jobs: | ||
| lint-and-test: | ||
| name: Lint + test (Python 3.12 + web) | ||
| runs-on: ubuntu-latest | ||
| # The Postgres service runs the same docker-compose dev image the | ||
| # local developer brings up via ``docker compose up -d | ||
| # gw2a-postgres``. Credentials match ``[tool.pytest_env]`` in the | ||
| # root ``pyproject.toml`` so ``uv run pytest`` finds a reachable | ||
| # ``DATABASE_URL`` without further wiring. The platform-managed | ||
| # health check gates the rest of the job until the DB is ready to | ||
| # accept connections (and auto-cleans the container on job exit). | ||
| services: | ||
| postgres: | ||
| image: postgres:16-alpine | ||
| env: | ||
| POSTGRES_USER: gw2analytics | ||
| POSTGRES_PASSWORD: gw2analytics | ||
| POSTGRES_DB: gw2analytics | ||
| ports: | ||
| - 5432:5432 | ||
| options: >- | ||
| --health-cmd "pg_isready -U gw2analytics" | ||
| --health-interval 5s | ||
| --health-timeout 5s | ||
| --health-retries 10 | ||
| steps: | ||
| - name: Checkout repository | ||
| uses: actions/checkout@v4 | ||
| with: | ||
| # Full history for `uv sync --frozen` and exact blame. | ||
| fetch-depth: 0 | ||
| - name: Install uv | ||
| uses: astral-sh/setup-uv@v3 | ||
| with: | ||
| enable-cache: true | ||
| cache-dependency-glob: "uv.lock" | ||
| - name: Set up Python 3.12 | ||
| run: uv python install 3.12 | ||
| - name: Sync workspace dependencies (frozen lock) | ||
| run: uv sync --frozen | ||
| - name: Ruff check | ||
| run: uv run ruff check --output-format=concise | ||
| - name: Ruff format check | ||
| run: uv run ruff format --check | ||
| - name: Mypy | ||
| run: uv run mypy libs apps --no-incremental | ||
| - name: Pytest | ||
| run: uv run pytest --tb=line -q | ||
| - name: Set up pnpm | ||
| uses: pnpm/action-setup@v4 | ||
| with: | ||
| version: 9 | ||
| - name: Set up Node.js 20 | ||
| uses: actions/setup-node@v4 | ||
| with: | ||
| node-version: 20 | ||
| cache: pnpm | ||
| - name: Install web deps (frozen lock) | ||
| working-directory: web | ||
| run: pnpm install --frozen-lockfile | ||
| # ---------------------------------------------------------------- | ||
| # OpenAPI codegen (Phase 4 tooling) | ||
| # ---------------------------------------------------------------- | ||
| # 1. Dump the FastAPI OpenAPI spec to /tmp via ``app.openapi()`` | ||
| # (avoids the uvicorn-boot + curl-loop race of an earlier draft). | ||
| # 2. Run ``openapi-typescript`` to (re)generate | ||
| # ``web/src/lib/api/schema.d.ts``. | ||
| # The committed ``schema.d.ts`` baseline ships in a followup | ||
| # commit alongside the ``git diff --exit-code`` drift gate -- once | ||
| # that lands, this CI pipeline will fail any PR that touches an | ||
| # endpoint without re-running ``pnpm generate:api``. | ||
| # The ``env`` block on step 1 supplies the dummy credentials that | ||
| # :class:`Settings` enforces without defaults. | ||
| # ---------------------------------------------------------------- | ||
| - name: OpenAPI: dump FastAPI spec (no port, no race) | ||
| run: uv run python web/scripts/dump_openapi.py > /tmp/openapi.json | ||
| env: | ||
| DATABASE_URL: "postgresql+psycopg://ci@localhost/ci" | ||
| S3_ENDPOINT: "ci" | ||
| S3_ACCESS_KEY: "ci" | ||
| S3_SECRET_KEY: "ci" | ||
| S3_BUCKET: "ci" | ||
| - name: OpenAPI: regenerate web TypeScript client | ||
| working-directory: web | ||
| run: pnpm exec openapi-typescript /tmp/openapi.json -o src/lib/api/schema.d.ts | ||
| - name: Type-check web | ||
| working-directory: web | ||
| run: pnpm exec tsc --noEmit | ||
| # ---------------------------------------------------------------- | ||
| # Vitest unit tests (Phase 4 unit-test scaffolding) | ||
| # ---------------------------------------------------------------- | ||
| # Runs the 3 component tests under tests/app/*.test.tsx with | ||
| # jsdom + @testing-library/react + jest-dom. Mocks next/link, | ||
| # next/font/google, and @/lib/env globally via tests/setup.ts | ||
| # so the suite is hermetic and the CI sandbox does not need | ||
| # network egress or a running gateway. | ||
| # ---------------------------------------------------------------- | ||
| - name: Web unit tests (vitest) | ||
| working-directory: web | ||
| run: pnpm exec vitest run --reporter=verbose | ||
| # The /tmp/openapi.json file is ephemeral -- clean it up so a | ||
| # later job in the same runner environment doesn't pick it up. | ||
| - name: OpenAPI: cleanup /tmp/openapi.json | ||
| if: always() | ||
| run: rm -f /tmp/openapi.json | ||