You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
ci: add test/lint matrix and PyPI trusted-publishing workflows
ci.yml runs lint + a Python 3.12/3.13/3.14 test matrix (100% coverage gate)
plus a floor job on the lowest supported deps (FastAPI 0.115 / pydantic 2.9)
via --resolution lowest-direct, on push/PR/workflow_call. publish.yml reuses
it on release and publishes to PyPI via trusted publishing (OIDC). Version-
conditional edges are skipped on the floor; adds httpx alongside httpx2 for the
old-starlette TestClient, PyPI metadata (classifiers, URLs) and a packaging
smoke test.
- Prefer pytest **fixtures** for reusable arrange values (request objects, configured apps, built artifacts) — typed, with a docstring and a `Returns:` section. Module level is only for error classes/enums that must exist at import time (they are used in type positions). Don't name a fixture `request` — it clashes with pytest's built-in.
95
95
- Lint everything: `just lint` (ruff format --check, ruff check, ty check). Run `uv run ruff format` to apply formatting. **ruff (preview) also formats Python code blocks inside Markdown** (`README.md`, `docs/**`), so keep doc snippets canonically formatted and re-run `just lint` after editing prose with code.
96
96
- Docs: **Material for MkDocs**, bilingual (EN default at `/`, RU at `/ru/`) via `mkdocs-static-i18n` (folder mode: `docs/en/**`, `docs/ru/**`; `nav_translations` localize the nav; language-specific assets like the Swagger SVG live per-language, shared CSS in `docs/stylesheets/`). API reference is auto-generated from Google docstrings via `mkdocstrings[python]` (`:::` blocks). Deps in the `docs` group (`~=`); serve `just docs`, strict build `just docs-build`. Published to GitHub Pages by `.github/workflows/docs.yml` (uv build + `upload-pages-artifact`/`deploy-pages`; Pages source = "GitHub Actions").
97
+
- CI/CD (`.github/workflows/`, uv + `astral-sh/setup-uv@v8`): `ci.yml` (on push-main / PR / `workflow_call`) — `lint` + `test` (Python matrix 3.12/3.13/3.14, `pytest --cov` → 100% gate) + `test-floor` (`uv sync --resolution lowest-direct` then **`uv run --no-sync pytest`** — `uv run` alone re-syncs to the lockfile; floor = FastAPI 0.115 / pydantic 2.9, **no** coverage gate since the `iter_route_contexts` branch can't run there). `publish.yml` (on release published) reuses `ci.yml` then publishes via **PyPI Trusted Publishing / OIDC** (`environment: pypi`, `id-token: write`, `uv build` + smoke `scripts/smoke_test.py` on wheel+sdist + `uv publish`, no token) — needs a one-time PyPI pending-publisher config.
98
+
- Version-conditional tests: edges that behave differently on old FastAPI/pydantic (PEP 695 `type`-alias return annotations, the broken-param-hint tolerance, lazy-include dedup) are guarded by `requires_modern_fastapi = skipif(not hasattr(fastapi.routing, "iter_route_contexts"))` — they run (and count toward 100%) on the default stack, skip on the floor. `monkeypatch.delattr(..., raising=False)` where the attribute is absent on the floor.
99
+
- Both `httpx` (old starlette `TestClient`, the FastAPI floor) and `httpx2` (new starlette) are in the dev group.
97
100
- Environment and build: uv (`uv sync`, `uv run python ...`), build backend `uv_build`.
98
101
- Run smoke checks against a live FastAPI app: `uv run python <script>` (`httpx2` for `TestClient` is in the dev group, so no `--with` is needed anymore).
0 commit comments