Skip to content

feat(api): backfill player summaries for pre-v0.8.4 fights (v0.8.5) #52

feat(api): backfill player summaries for pre-v0.8.4 fights (v0.8.5)

feat(api): backfill player summaries for pre-v0.8.4 fights (v0.8.5) #52

Workflow file for this run

# 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
# ----------------------------------------------------------------
# Playwright E2E (v0.7.2 web layer)
# ----------------------------------------------------------------
# The ``playwright.config.ts`` 2 ``webServer`` blocks (mock
# HTTP on 8080 + Next.js on 3000) handle the orchestration;
# ``isCI`` flips the Next.js command from ``pnpm dev`` to
# ``next build && next start`` for determinism. The
# ``--with-deps`` flag installs the system packages the
# chromium build needs (``libnss3``, ``libatk1.0``, etc.)
# on the bare ``ubuntu-latest`` runner.
# ----------------------------------------------------------------
- name: Install Playwright chromium
working-directory: web
run: pnpm exec playwright install --with-deps chromium
# ``playwright.config.ts`` flips the Next.js command to
# ``pnpm run build && pnpm run start -- -p 3000`` when
# ``isCI`` is truthy, so the ``webServer`` block handles
# the production build + serve cycle on its own. No
# explicit ``next build`` step is needed here.
- name: Playwright E2E tests
working-directory: web
run: pnpm exec playwright test
# Upload the Playwright HTML report on failure so the
# post-mortem is in the GitHub Actions artifacts tab.
- name: Upload Playwright report on failure
if: failure()
uses: actions/upload-artifact@v4
with:
name: playwright-report
path: web/playwright-report/
retention-days: 7
# Upload the per-test trace + screenshot artifacts on
# failure (``playwright.config.ts`` sets
# ``trace: "retain-on-failure"`` so the ``test-results/``
# directory is populated only when a test fails). The
# HTML report and the trace bundles are complementary:
# the report gives a high-level summary, the traces
# let the post-mortem replay a failing test step-by-step
# via ``npx playwright show-trace``.
- name: Upload Playwright traces on failure
if: failure()
uses: actions/upload-artifact@v4
with:
name: playwright-traces
path: web/test-results/
retention-days: 7
# 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