Run the examples/ unit test tier in CI - #192
Merged
Merged
Conversation
The unit-tests job invokes only pytest tests/unit/, and testpaths = ["tests"] means no default collection reaches examples/, so the relocated VLM-eval unit tier ran nowhere. Add an explicit step for it; each tier gets its own pytest session because the tier's conftest injects a fake lmms_eval that would leak into a shared one. The integration tier needs the real, undeclared lmms-eval and stays manual.
Codecov Report✅ All modified and coverable lines are covered by tests. 🚀 New features to boost your workflow:
|
Naeemkh
requested changes
Aug 26, 2026
Run it from its own ci-example.yml on the paths that can affect it rather than on every PR. kempnerforge/** is in the filter because the examples import core (the VLM-eval adapter alone has 10 core imports), so a core-only change can break an example tier without touching examples/ -- the same reason docs.yml filters on kempnerforge/**.
Listing kempnerforge/** made the filter nearly a no-op: 15 of the last 20 merged PRs touched core, so the workflow would have run on 18 of 20 PRs instead of 6. The unfiltered push-to-main trigger covers a core change that breaks an example tier instead, at one merge of latency.
Restore the unit-tests row and describe example-tests as its own job.
Naeemkh
reviewed
Aug 26, 2026
One job per example behind a dorny/paths-filter gate, so touching one example does not run another's tests. Both triggers are path-filtered and the workflow no longer lists its own path, which was matching on every workflow edit and so would have run every example's tests whenever one was added.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
ci-example.ymlruns the hermetic example test tiers, which sit outside the roottestpathsand so were collected by no CI step after Move VLM evaluation into examples/vlm/eval #184. One job per example behind adorny/paths-filtergate, so touching one example does not run another's tests. Today that isvlm-testsrunningpytest examples/vlm/eval/tests/unit; a second tier in the same example is one more- run:line.examples/vlm/**. The workflow's own path is deliberately not listed: it matched on every edit to the file, so adding an example would have run every example's tests.lmms_evalthat would leak into any tier sharing the session. The VLM-eval integration tier needs the real, undeclaredlmms-evaland stays manual.ci.ymlis byte-identical tomain; ruff and pyright scope unchanged.dorny/paths-filter@v3— the first action used here outsideactions/,astral-sh/andcodecov/.kempnerforge.lintandunit-tests. A path-filtered check cannot be made required — GitHub blocks every PR where it never reports — so these jobs are advisory unless someone adds them to the ruleset and accepts that.pyproject.tomlanduv.lockare not in the filter, so a dependency bump can break an example tier without touching any example directory. "Run every tier" is a different rule from per-example filtering, so it seems worth deciding separately.Testing
uv run pytest tests/unit/ -v --timeout=120on the final tree (2438705) — 1726 passed, 3 skipped in 237.76sfind_spec("lmms_eval")isNone,import lmms_evalraisesModuleNotFoundError, and no orphanedlmms_eval/directory is onsys.path.find_specalone is not sufficient:uv syncprunes the package's modules but leaves its task-data files, and that__init__.py-less directory reads as a namespace package. Result: 104 passed, exit 0.changesresolveddorny/paths-filter@v3and loggedFilter vlm = true/Changes output set to ["vlm"]; the gatedvlm-testsjob then reportedcollected 104 items/104 passed in 6.78s.b25ce48touched only.github/workflows/ci-example.yml,CHANGELOG.mdandCONTRIBUTING.md—CIran andCI (examples)produced no run at all.2438705then addedexamples/vlm/eval/README.mdandCI (examples)ran and passed.adapter.py::_first_stop, so it returns the last stop match instead of the first, gives1 failed, 103 passedand exit 1. Defect reverted.examples/vlm/eval/tests/unit, which exists on this base.examples/vlm/tests(added by Move VLM training configs into examples/vlm/ #193) does not, and naming it would exit 4 — confirmed by running it.uv run ruff check kempnerforge/ tests/ scripts/— All checks passed.uv run ruff format --check kempnerforge/ tests/ scripts/— 166 files already formatted.uv run pyright kempnerforge/— 0 errors, 0 warnings, 0 informations.ci-example.ymlparses to jobschanges+vlm-tests, withpermissions: contents/pull-requests: read;ci.ymlis byte-identical tomain.Closes #191