bstein-dev-home/testing/ci/publish_metrics.py

61 lines
2.2 KiB
Python

from __future__ import annotations
"""Command-line entry point for publishing CI test metrics."""
import argparse
import json
from pathlib import Path
from .summary import load_junit_summary, publish_quality_metrics
def _build_parser() -> argparse.ArgumentParser:
"""Build the CLI parser for the metrics publisher."""
parser = argparse.ArgumentParser(description="Publish test-suite metrics to Pushgateway")
parser.add_argument("--gateway", required=True, help="Pushgateway base URL")
parser.add_argument("--suite", required=True, help="Logical suite name")
parser.add_argument("--job", default="platform-quality-ci", help="Pushgateway job label")
parser.add_argument("--status", choices=("ok", "failed"), required=True, help="Gate outcome")
parser.add_argument("--junit", nargs="*", default=(), help="JUnit XML files to aggregate")
parser.add_argument("--quality-report", default="build/quality-gate.json", help="Quality gate JSON report")
return parser
def _load_quality_report(path: Path) -> tuple[float, int]:
"""Read workspace coverage/LOC summary from the quality gate JSON output."""
if not path.exists():
return 0.0, 0
payload = json.loads(path.read_text(encoding="utf-8"))
coverage = payload.get("workspace_line_coverage_percent")
if not isinstance(coverage, (int, float)):
coverage = 0.0
source_lines = payload.get("source_lines_over_500")
if not isinstance(source_lines, int):
source_lines = 0
return float(coverage), int(source_lines)
def main(argv: list[str] | None = None) -> int:
"""Parse arguments, aggregate JUnit files, and publish metrics."""
parser = _build_parser()
args = parser.parse_args(argv)
summary = load_junit_summary(Path(path) for path in args.junit)
coverage_percent, source_lines_over_500 = _load_quality_report(Path(args.quality_report))
publish_quality_metrics(
gateway=args.gateway,
suite=args.suite,
job=args.job,
status=args.status,
summary=summary,
workspace_line_coverage_percent=coverage_percent,
source_lines_over_500=source_lines_over_500,
)
return 0
if __name__ == "__main__":
raise SystemExit(main())