feat: run checks in docker

This commit is contained in:
2026-10-06 01:01:37 +01:00
parent ad3041ec56
commit 19f915081a
4 changed files with 18 additions and 27 deletions
+4 -11
View File
@@ -51,22 +51,15 @@ Maintain a deliberately small, self-hosted rota application for a non-profit bar
## Validation before handoff ## Validation before handoff
Run: All checks run inside Docker, never on the host:
```bash ```bash
python -m compileall -q app make check
pytest -q
``` ```
Prefer the containerized suite when the host Python environment is uncertain: That is `python -m compileall -q app && pytest -ra` in the `checks` service of `docker-compose.dev.yml`, which bind-mounts `app/`, `tests/` and `pyproject.toml` so it always validates the working tree. Do not run `pytest`, `uvicorn` or `python -m app.cli` against the host interpreter.
```bash The `dev` target of the `Dockerfile` installs `requirements-dev.txt` on top of the app image; the `checks` service supplies throwaway settings (`SECRET_KEY`, `DATABASE_URL`, `INITIAL_ADMIN_PASSWORD`), keeps `data/` inside the container, and does not read `.env`, so it is safe on a fresh clone.
make test-docker
# or
docker compose -f docker-compose.dev.yml --profile test run --rm tests
```
The `dev` target of the `Dockerfile` installs `requirements-dev.txt` on top of the app image; the `tests` service in `docker-compose.dev.yml` runs `pytest` with throwaway settings (`SECRET_KEY`, `DATABASE_URL`, `INITIAL_ADMIN_PASSWORD`). It bind-mounts `app/`, `tests/` and `pyproject.toml` so the suite always runs the working tree, keeps `data/` inside the container, and does not read `.env`, so it is safe on a fresh clone.
`docker-compose.yml` is the service stack only. Anything development-related (auto-reload, bind mounts, test runner) belongs in `docker-compose.dev.yml`. `docker-compose.yml` is the service stack only. Anything development-related (auto-reload, bind mounts, test runner) belongs in `docker-compose.dev.yml`.
+5 -5
View File
@@ -1,7 +1,7 @@
COMPOSE ?= docker compose COMPOSE ?= docker compose
COMPOSE_DEV = $(COMPOSE) -f docker-compose.dev.yml COMPOSE_DEV = $(COMPOSE) -f docker-compose.dev.yml
.PHONY: dev dev-up dev-down dev-logs test test-docker init-db seed-demo reminders .PHONY: dev dev-up dev-down dev-logs check test-docker init-db seed-demo reminders
dev: dev:
uvicorn app.main:app --reload uvicorn app.main:app --reload
@@ -16,12 +16,12 @@ dev-down:
dev-logs: dev-logs:
$(COMPOSE_DEV) logs -f app $(COMPOSE_DEV) logs -f app
test: # Compile check plus the test suite, inside Docker.
pytest -q check:
$(COMPOSE_DEV) --profile check run --rm --build checks
# Runs the suite inside Docker, independent of the host Python environment.
test-docker: test-docker:
$(COMPOSE_DEV) --profile test run --rm tests $(MAKE) check
init-db: init-db:
python -m app.cli init-db python -m app.cli init-db
+5 -7
View File
@@ -75,18 +75,16 @@ Example cron entry at 09:00 every day:
## Tests ## Tests
```bash Checks run in a container, so the host Python environment does not matter:
pytest -q
```
Or in a container, so the host Python environment does not matter:
```bash ```bash
make test-docker make check
# or # or
docker compose -f docker-compose.dev.yml --profile test run --rm tests docker compose -f docker-compose.dev.yml --profile check run --rm checks
``` ```
`make check` runs `python -m compileall -q app && pytest -ra` against the working tree.
## Project documentation ## Project documentation
- `AGENTS.md` — instructions and guardrails for coding agents/LLMs. - `AGENTS.md` — instructions and guardrails for coding agents/LLMs.
+4 -4
View File
@@ -1,6 +1,6 @@
# Development stack: code is bind-mounted, reload is on, no restart policy. # Development stack: code is bind-mounted, reload is on, no restart policy.
# Run standalone: docker compose -f docker-compose.dev.yml up --build # Run standalone: docker compose -f docker-compose.dev.yml up --build
# Tests: docker compose -f docker-compose.dev.yml run --rm tests # Checks: make check
services: services:
app: app:
build: build:
@@ -18,12 +18,12 @@ services:
- ${DATA_DIR:-./data}:/app/data - ${DATA_DIR:-./data}:/app/data
command: ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000", "--reload"] command: ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000", "--reload"]
tests: checks:
build: build:
context: . context: .
target: dev target: dev
profiles: profiles:
- test - check
environment: environment:
SECRET_KEY: test-only-secret-key SECRET_KEY: test-only-secret-key
DATABASE_URL: sqlite:///./data/test.db DATABASE_URL: sqlite:///./data/test.db
@@ -33,4 +33,4 @@ services:
- ./app:/app/app - ./app:/app/app
- ./tests:/app/tests - ./tests:/app/tests
- ./pyproject.toml:/app/pyproject.toml:ro - ./pyproject.toml:/app/pyproject.toml:ro
command: ["pytest", "-ra"] command: ["sh", "-c", "python -m compileall -q app && pytest -ra"]