.PHONY: dev lint test migrate run-api run-worker run-reconciler integration ci chart dev: uv sync lint: uv run ruff check . && uv run ruff format --check . && uv run mypy . test: uv run pytest tests/unit integration: uv run pytest tests/integration migrate: uv run python -m svcforge_core.migrate run-api: uv run uvicorn services.api.main:create_app --factory --reload --port 8000 run-worker: uv run python -m services.worker.main run-reconciler: uv run python -m services.reconciler.main # Every gate CI runs, except the image build — that needs a docker daemon and three # minutes, and the point of this target is to find out you failed before pushing. # Same commands as .gitea/workflows/ci.yaml, deliberately: a gate that only exists in CI # is a gate you debug through a web UI. ci: uv run ruff check . uv run ruff format --check . uv run mypy --strict . uv run pytest tests/unit --cov=libs/svcforge_core/domain --cov-fail-under=90 uv run pytest tests/integration uv run --with bandit bandit -r libs services -ll uv run --with pip-audit pip-audit --strict hadolint services/*/Dockerfile helm lint deploy/chart helm template svcforge deploy/chart >/dev/null # The chart's own gates. `helm template` is not a formality here: the image helper calls # `fail` on any digest that is not a sha256, so this catches an unbumped values.yaml. chart: helm lint deploy/chart helm template svcforge deploy/chart