Development setup¶
Install dev dependencies¶
uv sync --all-extras
source .venv/bin/activate
uv pip install --link-mode=copy -e ".[all]"
uv pip install --link-mode=copy -e "./library"
Tests¶
The test suite is registry-driven:
pytest # default run, no coverage
pytest tests/core -v # framework-feature coverage only
pytest tests/_registry -v # registry-driven conformance only
pytest -m "not slow" # skip slow training smoke tests
To see coverage locally, run the CI-style coverage command:
pytest --cov=nexuml --cov=nexuml_library \
--cov-report=term-missing \
--cov-report=xml:reports/coverage.xml
The terminal report shows total coverage and missing line ranges per file. The
XML report is written to reports/coverage.xml for tools that consume Cobertura
coverage. The failure threshold is configured in pyproject.toml under
[tool.coverage.report].
For a browsable report:
pytest --cov=nexuml --cov=nexuml_library --cov-report=html:reports/htmlcov
python -m http.server 8000 --directory reports/htmlcov
Then open http://localhost:8000.
Gated tests are skipped automatically when their prerequisites are missing:
requires_data— setNEXUML_RUN_DATA_TESTS=1and a validNEXUML_DATA_ROOT.requires_gpu— skipped when no CUDA device is available.requires_optional(name)— skipped when the optional dependency is missing.
Type checking¶
ty check
Linting and formatting¶
ruff check .
ruff format --check .
OpenSpec validation¶
openspec validate <change> --strict
CI gates¶
.github/workflows/ci.yml runs on every push and PR against main:
- Static job (
ika-runner): linting, formatting, type checking (see sections above). - Test job (
ika-runner-gpu): full pytest suite with the coverage gate frompyproject.toml.
Run all gates locally before opening a PR (see the sections above for individual commands). To trigger or monitor CI manually:
gh workflow run ci.yml --ref <branch>
gh run list --workflow ci.yml --limit 5
gh run watch <run-id>
gh run view <run-id> --log-failed
act can check YAML syntax but does not reproduce the self-hosted runner environment — treat it as a smoke check only.
Dependency management¶
uv add <package> # add runtime dep
uv add --dev <package> # add dev dep
uv lock --upgrade # update the lock file to latest packages
uv sync # install all deps from uv.lock
uv lock # regenerate uv.lock
Pull requests¶
Label every PR before merging — labels drive the automated release changelog generated on each v* tag.
| Label | Release section |
|---|---|
feature, enhancement |
🚀 Features |
bug, fix |
🐛 Bug Fixes |
chore, refactor |
🧰 Maintenance |
documentation, docs |
📝 Documentation |
ignore-for-release |
excluded entirely |
| (anything else) | Other Changes |
PRs without a matching label land in Other Changes. Add ignore-for-release to omit a PR from the changelog completely (e.g. CI tweaks, lock-file-only bumps).
When merging, use Squash and merge and delete the branch afterwards. Set the commit title to match the PR title exactly, and replace the default commit description with a bullet-point list of what changed:
feat(NEX-123): add export pipeline
- Add ONNX export step to pipeline registry
- Expose --output-format CLI flag
- Update docs with export examples
Docs¶
uv sync --extra docs
DISABLE_MKDOCS_2_WARNING=true mkdocs serve