diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f091ee71..7fb371be 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -263,6 +263,28 @@ jobs: - name: Quality checks run: make ci-quality-github + # Shared with the other repos' coverage jobs. It lives in its own public + # repo because a public repository -- this one -- cannot resolve an action + # from a private one. An earlier attempt to consume it from the private + # internal-workflows repo failed at `Set up job` on every matrix leg with + # "Unable to resolve action, not found", so no tests ran at all. + # + # Pinned by commit rather than tag: a tag can be repointed at new code, + # and pinning means a change to the action cannot reach us until we bump + # it deliberately. + # + # This owns the coverage artifact upload. The test-results upload below + # stays separate -- the action uploads one artifact, and these are two. + - name: Coverage summary + if: always() + uses: runpod/coverage-summary-action@65b35a32ecfd9c2f0dc2352394eca1decfba4915 + with: + format: cobertura + coverage-file: coverage.xml + results: pytest-results-*.xml + artifact-name: coverage-${{ matrix.python-version }} + if-no-files-found: warn + - name: Upload test results uses: actions/upload-artifact@v4 if: always() diff --git a/Makefile b/Makefile index c764d4d4..5907bd54 100644 --- a/Makefile +++ b/Makefile @@ -71,9 +71,11 @@ test-integration: # Run integration tests in parallel (auto-detect cores) test-integration-serial: # Run integration tests serially (for debugging) uv run pytest tests/integration/ -v -m integration +# The serial pass re-emits the XML after appending, or coverage.xml is left +# holding only the parallel run and undercounts. test-coverage: # Run tests with coverage report (parallel non-serial, then serial pass for state isolation) uv run pytest tests/ -v -n auto -m "not serial" --cov=runpod_flash --cov-report=xml - uv run pytest tests/ -v -m "serial" --cov=runpod_flash --cov-append --cov-report=term-missing + uv run pytest tests/ -v -m "serial" --cov=runpod_flash --cov-append --cov-report=term-missing --cov-report=xml test-coverage-serial: # Run tests with coverage report (serial execution) uv run pytest tests/ -v --cov=runpod_flash --cov-report=term-missing @@ -116,6 +118,20 @@ quality-check-strict: format-check lint typecheck test-coverage # Strict quality quality-check-serial: ci-quality-github-serial # Serial quality gate for debugging # GitHub Actions specific target -- canonical CI quality gate. +# The serial pass re-emits the XML after appending, or coverage.xml is left +# holding only the parallel run and undercounts. +# +# The serial pass, not the parallel one, is the real coverage gate: the +# parallel invocation passes --cov-fail-under=0 to suppress the partial +# number, while the serial one inherits --cov-fail-under=65 from pyproject +# addopts. Do not "align" the two flags -- that quietly disables the gate. +# +# make stops at the first failing recipe line, so if the parallel pass fails +# the re-emit never runs and coverage.xml holds the parallel subset. That is +# deliberate: guarding the parallel line with `-`/`|| true` so the serial pass +# always ran would let a red parallel suite exit 0. The weekly report only +# reads runs whose status is success, so an undercount on an already-failing +# run is not consumed by anything. ci-quality-github: # Quality checks with GitHub Actions formatting (parallel by default) @echo "::group::Code formatting check" uv run ruff format --check . @@ -127,7 +143,7 @@ ci-quality-github: # Quality checks with GitHub Actions formatting (parallel by uv run pytest tests/ --junitxml=pytest-results-parallel.xml -v -n auto -m "not serial" --cov=runpod_flash --cov-report=xml --cov-fail-under=0 @echo "::endgroup::" @echo "::group::Test suite with coverage (serial pass)" - uv run pytest tests/ --junitxml=pytest-results-serial.xml -v -m "serial" --cov=runpod_flash --cov-append --cov-report=term-missing + uv run pytest tests/ --junitxml=pytest-results-serial.xml -v -m "serial" --cov=runpod_flash --cov-append --cov-report=term-missing --cov-report=xml @echo "::endgroup::" ci-quality-github-serial: # Serial quality checks for GitHub Actions (for debugging) diff --git a/pyproject.toml b/pyproject.toml index 30eac1bd..ff5743c4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -119,7 +119,7 @@ ignore_missing_imports = true [tool.coverage.run] parallel = true -branch = false +branch = true source = ["runpod_flash"] omit = ["*/tests/*", "*/test_*.py", "*/__pycache__/*", "*/site-packages/*"]