Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 36 additions & 7 deletions .github/scripts/coverage_report.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import sys

PATCH_THRESHOLD = 80
TOTAL_THRESHOLD = 80


def get_total_coverage(coverage_json_path="coverage.json"):
Expand All @@ -25,6 +26,27 @@ def get_total_coverage(coverage_json_path="coverage.json"):
return (totals["covered_lines"] / num_statements) * 100


def format_coverage_report(coverage_json_path="coverage.json"):
"""Build a markdown table of per-file coverage from coverage.json."""
with open(coverage_json_path) as f:
data = json.load(f)

rows = []
for file_path, file_info in sorted(data["files"].items()):
totals = file_info["summary"]
num_statements = totals["num_statements"]
if num_statements == 0:
continue
pct = (totals["covered_lines"] / num_statements) * 100
missing = totals["missing_lines"]
rows.append(f"| {file_path} | {num_statements} | {missing} | {pct:.1f}% |")

if not rows:
return "No tracked files."
header = "| File | Stmts | Miss | Cover |\n| --- | --- | --- | --- |"
return header + "\n" + "\n".join(rows)


def get_changed_lines_pr():
"""Return dict of {filepath: set(line_numbers)} changed in this PR.

Expand Down Expand Up @@ -158,7 +180,7 @@ def create_check_run(name, conclusion, title, summary):


def run_ci():
"""CI mode: report total and patch coverage as GitHub Check Runs."""
"""CI mode: report total coverage via the job summary and patch coverage as a Check Run."""
coverage_path = "coverage.json"
if not os.path.exists(coverage_path):
print("Error: coverage.json not found. Tests may have failed.")
Expand All @@ -173,12 +195,13 @@ def run_ci():
f"Patch coverage: {patch_pct:.1f}% ({trackable_count} trackable lines changed)"
)

create_check_run(
name="Total Coverage",
conclusion="success",
title=f"Total Coverage: {total_pct:.1f}%",
summary=f"Overall project test coverage is **{total_pct:.1f}%**.",
)
summary_path = os.environ.get("GITHUB_STEP_SUMMARY")
if summary_path:
with open(summary_path, "a") as f:
f.write(f"## Total Coverage: {total_pct:.1f}%\n")
f.write(f"(threshold: {TOTAL_THRESHOLD}%)\n\n")
f.write(format_coverage_report(coverage_path))
f.write("\n")

patch_conclusion = "success" if patch_pct >= PATCH_THRESHOLD else "failure"
patch_summary = (
Expand All @@ -192,6 +215,12 @@ def run_ci():
summary=patch_summary,
)

if total_pct < TOTAL_THRESHOLD:
print(
f"FAIL: total coverage {total_pct:.1f}% is below {TOTAL_THRESHOLD}% threshold"
)
sys.exit(1)


def run_precommit():
"""Pre-commit mode: check patch coverage of staged changes, exit non-zero if < threshold."""
Expand Down
62 changes: 57 additions & 5 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ on:
branches: [ "main" ]

jobs:
test:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
Expand All @@ -22,15 +22,30 @@ jobs:
with:
python-version: "3.12"

- name: Install dependencies
run: |
uv pip install --system hatchling pytest pre-commit

- name: Check Code Formatting
run: |
uvx ruff format --check --exclude boilerplates/
uvx ruff check --select F401 --exclude boilerplates/

test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Install uv
uses: astral-sh/setup-uv@v3
with:
enable-cache: true

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.12"

- name: Install dependencies
run: |
uv pip install --system hatchling

- name: Validate Packing and Installation
run: |
# Builds the wheel and installs it the way a user would
Expand All @@ -40,3 +55,40 @@ jobs:
run: |
# Runs pytest, verifying that the installed package works
uv run pytest tests/

total-coverage:
if: github.event_name == 'pull_request'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Install uv
uses: astral-sh/setup-uv@v3
with:
enable-cache: true

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.12"

- name: Install dependencies
run: |
uv pip install --system hatchling

- name: Install package
run: |
uv pip install --system .

- name: Run tests with coverage
run: |
uv run pytest --cov=synaflow --cov-report=json --cov-report=term

- name: Report coverage to GitHub
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PR_HEAD_SHA: ${{ github.event.pull_request.head.sha }}
run: |
python .github/scripts/coverage_report.py
42 changes: 0 additions & 42 deletions .github/workflows/test-coverage.yml

This file was deleted.

Loading