CI: run migrations + integration slice against real Postgres; add ruff and pip-audit gates #65

Closed
opened 2026-07-18 05:31:28 +00:00 by claude-bot · 2 comments
Contributor

CI/CD test jobs run only compileall + pytest on the aiosqlite suite
(ci.yml:20-29, cd.yml:30-37). Nothing validates the Alembic chain or
Postgres-specific behavior before code reaches the dev server, and no
dependency-audit step exists. Add: a postgres:16-alpine service container;
alembic upgrade head against it (fresh DB — catches chain errors); the
Postgres-tier tests from F-29 once they exist; ruff check (start with a
permissive rule set); pip-audit (or Renovate's vulnerability alerts if
enabled instance-side). Keep the fast SQLite suite as the bulk tier.

Acceptance criteria:

  • PR breaking a migration fails CI before merge
  • ruff + pip-audit gate PRs
  • CI wall time stays acceptable (document it)

Filed from the 2026-07-17 codebase audit (docs/.internal/report-2026-07-17.md), finding F-26.

CI/CD test jobs run only `compileall` + `pytest` on the aiosqlite suite (ci.yml:20-29, cd.yml:30-37). Nothing validates the Alembic chain or Postgres-specific behavior before code reaches the dev server, and no dependency-audit step exists. Add: a postgres:16-alpine service container; `alembic upgrade head` against it (fresh DB — catches chain errors); the Postgres-tier tests from F-29 once they exist; `ruff check` (start with a permissive rule set); `pip-audit` (or Renovate's vulnerability alerts if enabled instance-side). Keep the fast SQLite suite as the bulk tier. **Acceptance criteria:** - [ ] PR breaking a migration fails CI before merge - [ ] ruff + pip-audit gate PRs - [ ] CI wall time stays acceptable (document it) --- _Filed from the 2026-07-17 codebase audit (`docs/.internal/report-2026-07-17.md`), finding F-26._
Author
Contributor

Picking this up as part of v1.1.0 Phase 1 (with #68). Plan for ci.yml: add a postgres:16-alpine service, then steps for (1) ruff check with a permissive starter config, (2) alembic upgrade head against the fresh PG (catches migration-chain errors), (3) the SQLite bulk suite (pytest -q, which excludes the PG marker by default), (4) the Postgres integration tier (WEATHERBOT_TEST_DB=postgres pytest -m postgres), and (5) pip-audit. ruff/pip-audit added to requirements-test.txt. cd.yml needs no PG service since its pytest run excludes the marker by default. pip-audit gating will be verified against the current lockfile first so it doesn't wedge CI on an unfixable transitive advisory.

Picking this up as part of v1.1.0 Phase 1 (with #68). Plan for `ci.yml`: add a `postgres:16-alpine` service, then steps for (1) `ruff check` with a permissive starter config, (2) `alembic upgrade head` against the fresh PG (catches migration-chain errors), (3) the SQLite bulk suite (`pytest -q`, which excludes the PG marker by default), (4) the Postgres integration tier (`WEATHERBOT_TEST_DB=postgres pytest -m postgres`), and (5) `pip-audit`. ruff/pip-audit added to `requirements-test.txt`. `cd.yml` needs no PG service since its `pytest` run excludes the marker by default. pip-audit gating will be verified against the current lockfile first so it doesn't wedge CI on an unfixable transitive advisory.
Author
Contributor

Done in #94 (merged to main). CI now runs ruff (permissive starter: E9/F63/F7), alembic upgrade head against a fresh Postgres (catches migration-chain errors), the SQLite bulk tier, and the Postgres integration tier.

Two implementation notes worth recording:

  • Postgres via docker run, not services: — the act_runner didn't provide a reachable service container (the first run hung on the service health-wait). CI now starts Postgres with docker run inside the job (attaching it to the job's docker network when containerized, else publishing to the host) and auto-detects the working host in a bounded readiness probe. Added a 20-minute job timeout so no step can wedge the shared runner again.
  • pip-audit is advisory (non-blocking) for now--strict fails on a backlog of advisories in the pinned stack (starlette, pyjwt, python-multipart, python-dotenv, setuptools) that the pending Renovate upgrades (#30–#37) clear. It's a one-line change (drop continue-on-error, add --strict) once that backlog lands.

cd.yml is unchanged — its pytest run excludes the postgres marker by default.

Done in #94 (merged to `main`). CI now runs ruff (permissive starter: E9/F63/F7), `alembic upgrade head` against a fresh Postgres (catches migration-chain errors), the SQLite bulk tier, and the Postgres integration tier. Two implementation notes worth recording: - **Postgres via `docker run`, not `services:`** — the act_runner didn't provide a reachable service container (the first run hung on the service health-wait). CI now starts Postgres with `docker run` inside the job (attaching it to the job's docker network when containerized, else publishing to the host) and auto-detects the working host in a bounded readiness probe. Added a 20-minute job timeout so no step can wedge the shared runner again. - **pip-audit is advisory (non-blocking) for now** — `--strict` fails on a backlog of advisories in the pinned stack (starlette, pyjwt, python-multipart, python-dotenv, setuptools) that the pending Renovate upgrades (#30–#37) clear. It's a one-line change (drop `continue-on-error`, add `--strict`) once that backlog lands. `cd.yml` is unchanged — its `pytest` run excludes the postgres marker by default.
Sign in to join this conversation.
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
rbrooks/WeatherBot#65
No description provided.