From b2a7d723059d32bc5cd120f6ef4971aecbd0e86d Mon Sep 17 00:00:00 2001 From: codex Date: Mon, 20 Apr 2026 08:17:18 -0300 Subject: [PATCH] ci(ananke): publish docs_naming from hygiene doc/naming contracts --- scripts/publish_quality_metrics.py | 56 ++++++++---------------------- scripts/quality_gate.sh | 16 +++++++-- 2 files changed, 29 insertions(+), 43 deletions(-) diff --git a/scripts/publish_quality_metrics.py b/scripts/publish_quality_metrics.py index b3ad032..48c5802 100755 --- a/scripts/publish_quality_metrics.py +++ b/scripts/publish_quality_metrics.py @@ -18,7 +18,6 @@ DEFAULT_PUSHGATEWAY_URL = "http://platform-quality-gateway.monitoring.svc.cluste SOURCE_SCAN_ROOTS = ("cmd", "internal", "scripts", "testing") SOURCE_EXTENSIONS = {".go", ".py", ".sh"} QUALITY_SUCCESS_STATES = {"ok", "pass", "passed", "success", "compliant"} -COVERAGE_GATE_PERCENT = 95.0 def _escape_label(value: str) -> str: @@ -170,6 +169,17 @@ def _read_exit_code(path: Path) -> int: return 1 +def _read_status(path: Path, default: str = "failed") -> str: + if not path.exists(): + return default + raw = path.read_text(encoding="utf-8").strip().lower() + if raw in {"ok", "pass", "passed", "success"}: + return "ok" + if raw in {"failed", "fail", "error"}: + return "failed" + return default + + def _load_json(path: Path) -> dict | None: if not path.exists(): return None @@ -209,20 +219,6 @@ def _supply_chain_check_status(build_dir: Path) -> str: return "failed" -def _parse_check_overrides(raw_checks: list[str]) -> dict[str, str]: - overrides: dict[str, str] = {} - for entry in raw_checks: - if ":" not in entry: - continue - check_name, check_status = entry.split(":", 1) - check_name = check_name.strip() - check_status = check_status.strip().lower() - if not check_name or not check_status: - continue - overrides[check_name] = check_status - return overrides - - def parse_args(argv: list[str]) -> argparse.Namespace: parser = argparse.ArgumentParser(description=__doc__) parser.add_argument( @@ -241,13 +237,6 @@ def parse_args(argv: list[str]) -> argparse.Namespace: "--coverage-percent-file", default=os.getenv("ANANKE_QUALITY_COVERAGE_PERCENT_FILE", "build/coverage-percent.txt"), ) - parser.add_argument("--tests-passed", type=int, default=None) - parser.add_argument("--tests-failed", type=int, default=None) - parser.add_argument("--tests-error", type=int, default=None) - parser.add_argument("--tests-skipped", type=int, default=None) - parser.add_argument("--coverage-percent", type=float, default=None) - parser.add_argument("--source-lines-over-500", type=int, default=None) - parser.add_argument("--check", action="append", default=[]) parser.add_argument( "--timeout-seconds", type=float, @@ -297,36 +286,21 @@ def main(argv: list[str] | None = None) -> int: resolved_ok = max(args.local_ok, remote_ok) resolved_failed = max(args.local_failed, remote_failed) - tests = _parse_go_test_counts(Path(os.getenv("ANANKE_QUALITY_OUTPUT_FILE", str(build_dir / "quality-gate.out")))) - if args.tests_passed is not None: - tests["passed"] = args.tests_passed - if args.tests_failed is not None: - tests["failed"] = args.tests_failed - if args.tests_error is not None: - tests["errors"] = args.tests_error - if args.tests_skipped is not None: - tests["skipped"] = args.tests_skipped - coverage_percent = _read_coverage_percent(args.coverage_percent_file) - if args.coverage_percent is not None: - coverage_percent = args.coverage_percent - source_lines_over_500 = _count_source_files_over_limit(repo_root, max_lines=500) - if args.source_lines_over_500 is not None: - source_lines_over_500 = args.source_lines_over_500 - + tests = _parse_go_test_counts(Path(os.getenv("ANANKE_QUALITY_OUTPUT_FILE", str(build_dir / "quality-gate.out")))) gate_rc = _read_exit_code(Path(os.getenv("ANANKE_QUALITY_EXIT_CODE_PATH", str(build_dir / "quality-gate.rc")))) + docs_status = _read_status(Path(os.getenv("ANANKE_QUALITY_DOCS_STATUS_PATH", str(build_dir / "docs-naming.status")))) gate_failed = gate_rc != 0 checks = { "tests": "failed" if gate_failed or tests["failed"] > 0 else "ok", - "coverage": "ok" if coverage_percent >= COVERAGE_GATE_PERCENT else "failed", + "coverage": "ok" if coverage_percent >= 95.0 else "failed", "loc": "ok" if source_lines_over_500 == 0 else "failed", - "docs_naming": "not_applicable", + "docs_naming": docs_status, "gate_glue": "ok", "sonarqube": _sonarqube_check_status(build_dir), "supply_chain": _supply_chain_check_status(build_dir), } - checks.update(_parse_check_overrides(args.check)) payload = _build_payload( args.suite, args.trigger, diff --git a/scripts/quality_gate.sh b/scripts/quality_gate.sh index ed49448..f56a4d4 100755 --- a/scripts/quality_gate.sh +++ b/scripts/quality_gate.sh @@ -2,6 +2,9 @@ set -euo pipefail REPO_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +BUILD_DIR="${REPO_DIR}/build" +COVERAGE_PROFILE="${BUILD_DIR}/coverage.out" +COVERAGE_PERCENT_FILE="${BUILD_DIR}/coverage-percent.txt" QUALITY_METRICS_ENABLED="${ANANKE_QUALITY_METRICS_ENABLED:-1}" QUALITY_METRICS_FILE="${ANANKE_QUALITY_METRICS_FILE:-/var/lib/ananke/quality-gate.prom}" QUALITY_STATE_FILE="${ANANKE_QUALITY_STATE_FILE:-/var/lib/ananke/quality-gate.state}" @@ -132,9 +135,17 @@ quality_gate_finalize() { trap 'quality_gate_finalize $?' EXIT cd "${REPO_DIR}" +mkdir -p "${BUILD_DIR}" +rm -f "${COVERAGE_PROFILE}" "${COVERAGE_PERCENT_FILE}" +printf 'failed\n' > "${BUILD_DIR}/docs-naming.status" -echo "[quality] unit tests" -go test ./... +echo "[quality] unit tests + workspace coverage profile" +go test -coverprofile="${COVERAGE_PROFILE}" ./... +coverage_percent="$(go tool cover -func="${COVERAGE_PROFILE}" | awk '/^total:/ {gsub("%","",$3); print $3}')" +if [[ -z "${coverage_percent}" ]]; then + coverage_percent="0" +fi +printf '%s\n' "${coverage_percent}" > "${COVERAGE_PERCENT_FILE}" echo "[quality] hygiene: doc contracts" cd testing @@ -142,6 +153,7 @@ go test ./hygiene -run TestHygieneContracts/doc_contract -count=1 echo "[quality] hygiene: naming contracts" go test ./hygiene -run TestHygieneContracts/naming_contract -count=1 +printf 'ok\n' > "${BUILD_DIR}/docs-naming.status" echo "[quality] hygiene: LOC limits" go test ./hygiene -run TestHygieneContracts/loc_limit -count=1