ci: fix coverage target, pip-audit scope, bandit config
ci / lint (push) Successful in 35s
ci / unit (push) Successful in 1m11s
ci / types (push) Successful in 1m22s
ci / dockerfile (push) Successful in 4s
ci / security (push) Successful in 1m28s
ci / integration (push) Successful in 1m36s
ci / image (reconciler) (push) Failing after 17m0s
ci / image (api) (push) Failing after 17m1s
ci / image (worker) (push) Failing after 13m8s
ci / bump (push) Has been skipped
ci / lint (push) Successful in 35s
ci / unit (push) Successful in 1m11s
ci / types (push) Successful in 1m22s
ci / dockerfile (push) Successful in 4s
ci / security (push) Successful in 1m28s
ci / integration (push) Successful in 1m36s
ci / image (reconciler) (push) Failing after 17m0s
ci / image (api) (push) Failing after 17m1s
ci / image (worker) (push) Failing after 13m8s
ci / bump (push) Has been skipped
- --cov pointed at libs/svcforge_core/domain, a path that does not exist (the package nests one level deeper). Coverage measured 0.00% of the code. Use the module form, which is layout-independent. - pip-audit --strict cannot audit our own editable, not-on-PyPI packages. Audit the locked dependency set instead and keep --strict. - bandit re-reports B608/B104, which ruff's S ruleset already enforces with justified per-line noqa it cannot see. Skipped in config, with reasons. - registry host was git.oci-oci; it is gitea.oci-oci. - integration job set SVCFORGE_PG_DSN; conftest reads SVCFORGE_TEST_DSN.
This commit is contained in:
@@ -76,7 +76,13 @@ jobs:
|
|||||||
# The gate is on domain/ alone, and only domain/. It is pure, has no I/O, and needs
|
# The gate is on domain/ alone, and only domain/. It is pure, has no I/O, and needs
|
||||||
# no mocks — there is no excuse for a gap there. Pointing this at the whole repo
|
# no mocks — there is no excuse for a gap there. Pointing this at the whole repo
|
||||||
# would let untested SQL be paid for by well-tested pure functions.
|
# would let untested SQL be paid for by well-tested pure functions.
|
||||||
run: uv run pytest tests/unit --cov=libs/svcforge_core/domain --cov-fail-under=90
|
#
|
||||||
|
# `--cov=svcforge_core.domain` — the MODULE, not a path. `--cov=libs/svcforge_core/domain`
|
||||||
|
# is a path that does not exist (the package nests one level deeper, at
|
||||||
|
# libs/svcforge_core/svcforge_core/domain), so coverage measured nothing and reported
|
||||||
|
# 0.00%. A path-based --cov that misses silently reports 0 rather than erroring, so
|
||||||
|
# without a --cov-fail-under this reads as a passing coverage gate over no code at all.
|
||||||
|
run: uv run pytest tests/unit --cov=svcforge_core.domain --cov-fail-under=90
|
||||||
|
|
||||||
# --- stages 4+5: migrate, then integration against that schema -----------------------
|
# --- stages 4+5: migrate, then integration against that schema -----------------------
|
||||||
integration:
|
integration:
|
||||||
@@ -143,7 +149,10 @@ jobs:
|
|||||||
# `--with`, not a dev dependency: bandit is a CI tool, not something the project
|
# `--with`, not a dev dependency: bandit is a CI tool, not something the project
|
||||||
# imports, and ruff's S ruleset already runs its checks in the lint stage. This is
|
# imports, and ruff's S ruleset already runs its checks in the lint stage. This is
|
||||||
# the belt to that suspenders — -ll reports medium severity and above only.
|
# the belt to that suspenders — -ll reports medium severity and above only.
|
||||||
run: uv run --with bandit bandit -r libs services -ll
|
#
|
||||||
|
# `bandit[toml]` + `-c pyproject.toml`: without the toml extra bandit cannot read
|
||||||
|
# its own config and silently ignores it, which looks identical to a clean run.
|
||||||
|
run: uv run --with 'bandit[toml]' bandit -c pyproject.toml -r libs services -ll
|
||||||
|
|
||||||
- name: gitleaks (secret scan)
|
- name: gitleaks (secret scan)
|
||||||
# Pinned by digest and run directly, so the command is the documented one rather
|
# Pinned by digest and run directly, so the command is the documented one rather
|
||||||
@@ -155,7 +164,18 @@ jobs:
|
|||||||
|
|
||||||
- name: pip-audit (dependency CVEs)
|
- name: pip-audit (dependency CVEs)
|
||||||
# --strict fails on an audit error rather than shrugging and reporting clean.
|
# --strict fails on an audit error rather than shrugging and reporting clean.
|
||||||
run: uv run --with pip-audit pip-audit --strict
|
#
|
||||||
|
# Audits the LOCKED dependency set, not the installed environment. Auditing the env
|
||||||
|
# means auditing `svcforge` and `svcforge-core` too, which are ours, are installed
|
||||||
|
# editable, and are not on PyPI — under --strict that is a hard error ("distribution
|
||||||
|
# marked as editable"), so the choice was to drop --strict or to stop asking PyPI
|
||||||
|
# about packages it has never heard of. This asks about the 56 that actually came
|
||||||
|
# from PyPI, and keeps --strict.
|
||||||
|
run: |
|
||||||
|
uv export --frozen --no-dev \
|
||||||
|
--no-emit-project --no-emit-package svcforge-core \
|
||||||
|
-o /tmp/requirements-audit.txt
|
||||||
|
uv run --with pip-audit pip-audit --strict -r /tmp/requirements-audit.txt
|
||||||
|
|
||||||
# --- stage 9: hadolint ---------------------------------------------------------------
|
# --- stage 9: hadolint ---------------------------------------------------------------
|
||||||
dockerfile:
|
dockerfile:
|
||||||
|
|||||||
@@ -72,6 +72,23 @@ known-first-party = ["svcforge_core", "services"]
|
|||||||
# input that reaches a helm release name.
|
# input that reaches a helm release name.
|
||||||
"tests/e2e/**" = ["S101", "S603", "S607"]
|
"tests/e2e/**" = ["S101", "S603", "S607"]
|
||||||
|
|
||||||
|
[tool.bandit]
|
||||||
|
# bandit is the belt to ruff's suspenders: ruff's `S` ruleset IS flake8-bandit and runs on
|
||||||
|
# every file in the lint stage. These two skips are the rules ruff already enforces here,
|
||||||
|
# where each real site carries an individually justified `# noqa` that bandit cannot see —
|
||||||
|
# so bandit re-reports them as findings that ruff has already adjudicated.
|
||||||
|
#
|
||||||
|
# B608 (SQL built by string) == ruff S608. Every occurrence interpolates `_COLUMNS`, a
|
||||||
|
# module constant. Tenant input goes through psycopg parameters, never the f-string,
|
||||||
|
# and ruff fails the build if that ever changes.
|
||||||
|
# B104 (bind 0.0.0.0) == ruff S104. A container must bind all interfaces; the pod's
|
||||||
|
# network namespace is the boundary, not the listen address.
|
||||||
|
#
|
||||||
|
# Nothing else is skipped. If you add a third, justify it here or you are just turning the
|
||||||
|
# gate off one rule at a time.
|
||||||
|
skips = ["B608", "B104"]
|
||||||
|
exclude_dirs = [".venv", "tests"]
|
||||||
|
|
||||||
[tool.mypy]
|
[tool.mypy]
|
||||||
strict = true
|
strict = true
|
||||||
python_version = "3.12"
|
python_version = "3.12"
|
||||||
|
|||||||
Reference in New Issue
Block a user