diff --git a/.forgejo/workflows/ci.yml b/.forgejo/workflows/ci.yml index 181a577..5849df1 100644 --- a/.forgejo/workflows/ci.yml +++ b/.forgejo/workflows/ci.yml @@ -42,4 +42,6 @@ jobs: run: pip install -e ".[dev]" - name: Run test suite - run: pytest -q + # `python -m pytest` puts the repo root on sys.path so the test modules + # can `import tests.*` (the pytest console script would not). + run: python -m pytest -q diff --git a/.githooks/pre-push b/.githooks/pre-push new file mode 100755 index 0000000..e17fb43 --- /dev/null +++ b/.githooks/pre-push @@ -0,0 +1,11 @@ +#!/usr/bin/env bash +# +# Pre-push gate: run the local CI checks (ruff + mypy + pytest) before allowing +# a push. Blocks the push on any failure. +# +# Enable in a fresh clone with: +# git config core.hooksPath .githooks +# Bypass a single push with: +# git push --no-verify +# +exec "$(git rev-parse --show-toplevel)/scripts/check.sh" diff --git a/README.md b/README.md index aa7bf54..97a9b20 100644 --- a/README.md +++ b/README.md @@ -157,9 +157,22 @@ Für Details siehe [`docs/SECURITY_AND_OPERATIONS.md`](docs/SECURITY_AND_OPERATI ```bash pip install -e ".[dev]" -pytest -q +python -m pytest -q ``` +`python -m pytest` (statt des `pytest`-Skripts) legt das Repo-Root auf +`sys.path`, damit die Testmodule `import tests.*` auflösen. + +**Lokales CI-Gate:** `scripts/check.sh` bündelt `ruff` + `mypy` + `pytest` +(spiegelt `.forgejo/workflows/ci.yml`). Als Pre-Push-Hook aktivieren — er +blockt einen Push bei Fehlern: + +```bash +git config core.hooksPath .githooks # einmalig pro Clone +``` + +Einen einzelnen Push im Notfall umgehen: `git push --no-verify`. + Die Test-Suite deckt die Prompt-Eingabeschicht (Datei- und URL-Quellen inkl. SSRF-Abwehr mit gemockter DNS-Auflösung und DNS-Pinning), die Konfigurationsauflösung (inkl. `${ENV}`-Expansion), die CLI-Validierung, die diff --git a/scripts/check.sh b/scripts/check.sh new file mode 100755 index 0000000..5f7fdd7 --- /dev/null +++ b/scripts/check.sh @@ -0,0 +1,41 @@ +#!/usr/bin/env bash +# +# Local CI gate: lint + type-check + tests. Mirrors .forgejo/workflows/ci.yml +# so the same checks run before a push even without a Forgejo Actions runner. +# +# Run manually: scripts/check.sh +# Run automatically: git config core.hooksPath .githooks (see .githooks/pre-push) +# Bypass once (emergency): git push --no-verify +# +set -uo pipefail + +cd "$(git rev-parse --show-toplevel)" || exit 1 + +# Prefer the project venv's tools if present, else fall back to PATH. +BIN="" +if [ -x ".venv/bin/ruff" ]; then BIN=".venv/bin/"; fi + +fail=0 +run() { + local label=$1; shift + echo "== ${label} ==" + if "$@"; then + echo " OK" + else + echo " FAILED" + fail=1 + fi +} + +run "ruff (lint)" "${BIN}ruff" check src/ tests/ +run "mypy (types)" "${BIN}mypy" +# Use `python -m pytest` (not the pytest console script) so the repo root is on +# sys.path — the test modules import `from tests.test_docker_ops import ...`. +run "pytest (tests)" "${BIN}python" -m pytest -q + +echo +if [ "$fail" -ne 0 ]; then + echo "CI gate FAILED — fix the above or push with --no-verify to bypass." + exit 1 +fi +echo "CI gate passed."