## What
Adds the project's first **CI test workflow** —
`.github/workflows/test.yml` (job "CI"). Until now the only workflow was
`publish.yml`; tests never ran in CI. This gates every push to
`main`/`master` and every PR on (a) the full suite passing and (b)
**>90% by-branch coverage on changed code**.
## The workflow
- **Triggers:** `push` to `main`/`master`, and all `pull_request`s.
- **Env:** Python 3.12 (reliable CPU torch wheels),
`actions/checkout@v5` with `fetch-depth: 0` (diff-cover needs
base-branch history), `actions/setup-python@v5` with pip cache.
- **Real torch:** installs the CPU wheel from
`download.pytorch.org/whl/cpu`, so `tests/test_pack_split.py` (which
swaps the mock torch for real torch) actually executes rather than
skipping — its branch coverage counts.
- **Tests + coverage:** `pytest --cov=NRS --cov-branch --cov-report=xml
--cov-report=term-missing`. Any test failure fails the job.
- **Branch-coverage gate on the diff:** `diff-cover coverage.xml
--compare-branch=<base> --branch-coverage --fail-under=90`. Base is
`origin/${{ github.base_ref }}` for PRs (falling back to `origin/main`).
The `--branch-coverage` flag is required — diff-cover otherwise scores
only line coverage even when fed branch data in the Cobertura XML. Gate
is on **changed** code, not total project coverage, so a no-Python PR
passes trivially.
## Deliberately NOT touched
`pyproject.toml` is untouched (test deps live in the workflow), so this
change cannot trigger `publish.yml` or the held v1.0.0 version bump.
## Local validation
- `pytest --cov=NRS --cov-branch ...` → **42 passed**; total NRS branch
coverage ~79% (informational; the gate is diff-only, not total).
- `diff-cover coverage.xml --compare-branch=origin/main
--branch-coverage --fail-under=90` → passes (this branch changes no
Python).
- YAML parses cleanly; `coverage.xml`/`.coverage` already gitignored —
no artifacts committed.
## Note
Making this check **required** is a branch-protection repo setting you
control (GitHub → Settings → Branches).
49 lines
1.3 KiB
YAML
49 lines
1.3 KiB
YAML
name: CI
|
|
|
|
on:
|
|
push:
|
|
branches:
|
|
- main
|
|
- master
|
|
pull_request:
|
|
|
|
permissions:
|
|
contents: read
|
|
|
|
jobs:
|
|
test:
|
|
name: Test suite with branch coverage gate
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- name: Check out code
|
|
uses: actions/checkout@v5
|
|
with:
|
|
fetch-depth: 0
|
|
|
|
- name: Set up Python
|
|
uses: actions/setup-python@v5
|
|
with:
|
|
python-version: "3.12"
|
|
cache: "pip"
|
|
|
|
- name: Install real CPU torch
|
|
run: pip install torch --index-url https://download.pytorch.org/whl/cpu
|
|
|
|
- name: Install test tooling
|
|
run: pip install pytest pytest-cov diff-cover
|
|
|
|
- name: Run tests with branch coverage
|
|
run: pytest --cov=NRS --cov-branch --cov-report=xml --cov-report=term-missing
|
|
|
|
- name: Determine base branch for diff-cover
|
|
id: base
|
|
run: |
|
|
base_ref="origin/main"
|
|
if [ "${{ github.event_name }}" = "pull_request" ] && git rev-parse --verify "origin/${{ github.base_ref }}" >/dev/null 2>&1; then
|
|
base_ref="origin/${{ github.base_ref }}"
|
|
fi
|
|
echo "ref=${base_ref}" >> "$GITHUB_OUTPUT"
|
|
|
|
- name: Enforce 90% branch coverage on changed code
|
|
run: diff-cover coverage.xml --compare-branch=${{ steps.base.outputs.ref }} --branch-coverage --fail-under=90
|