#!/usr/bin/env python3 from __future__ import annotations import json import os from pathlib import Path def read_lcov_summary(lcov_path: Path) -> tuple[int, int, int, int]: line_found = 0 line_hit = 0 function_found = 0 function_hit = 0 with lcov_path.open("r", encoding="utf-8") as fh: for raw_line in fh: line = raw_line.strip() try: if line.startswith("LF:"): line_found += int(line[3:]) elif line.startswith("LH:"): line_hit += int(line[3:]) elif line.startswith("FNF:"): function_found += int(line[4:]) elif line.startswith("FNH:"): function_hit += int(line[4:]) except ValueError: continue return line_found, line_hit, function_found, function_hit def rate(hit: int, found: int) -> float: return round((hit / found) * 100, 2) if found else 0.0 def main() -> None: stage_dir = Path(os.environ["COVERAGE_STAGE_DIR"]) lcov_path = Path(os.environ["COVERAGE_OUTPUT_DIR"]) / "lcov.info" line_found, line_hit, function_found, function_hit = read_lcov_summary(lcov_path) manifest = { "schema_version": 1, "generated_at": os.environ["COVERAGE_RUN_TIMESTAMP"], "generated_date": os.environ["COVERAGE_RUN_DATE"], "repository": os.environ["GITHUB_REPOSITORY"], "branch": os.environ["COVERAGE_BRANCH_NAME"], "branch_slug": os.environ["COVERAGE_BRANCH_SLUG"], "sha": os.environ["GITHUB_SHA"], "short_sha": os.environ["COVERAGE_SHORT_SHA"], "run_id": os.environ["GITHUB_RUN_ID"], "run_number": os.environ["GITHUB_RUN_NUMBER"], "run_attempt": os.environ["GITHUB_RUN_ATTEMPT"], "event_name": os.environ["GITHUB_EVENT_NAME"], "bucket": os.environ["COVERAGE_BUCKET"], "object_prefix": os.environ["COVERAGE_OBJECT_PREFIX"], "archive_name": os.environ["COVERAGE_ARCHIVE_NAME"], "manifest_name": os.environ["COVERAGE_MANIFEST_NAME"], "archive_key": os.environ["COVERAGE_ARCHIVE_KEY"], "manifest_key": os.environ["COVERAGE_MANIFEST_KEY"], "report_dir": os.environ["COVERAGE_SHORT_SHA"], "report_index": f"{os.environ['COVERAGE_SHORT_SHA']}/html/index.html", "lcov_path": f"{os.environ['COVERAGE_SHORT_SHA']}/lcov.info", "summary": { "lines": { "found": line_found, "hit": line_hit, "rate": rate(line_hit, line_found), }, "functions": { "found": function_found, "hit": function_hit, "rate": rate(function_hit, function_found), }, }, } manifest_path = stage_dir / os.environ["COVERAGE_MANIFEST_NAME"] manifest_path.write_text(json.dumps(manifest, indent=2) + "\n", encoding="utf-8") if __name__ == "__main__": main()