Testing & CI
The three checks the PR CI runs — backend pytest, UI type-check, and the web smoke build — and how to run them locally before you push.
Every PR runs the same three checks in CI that you can run locally. Run them before you push and you'll rarely be surprised by a red PR.
The three local commands
| What | Command |
|---|---|
| Backend pytest | uv run pytest |
| UI type-check | cd ui ; npx vue-tsc --noEmit |
| UI web smoke build | cd ui ; npm run web:build |
vue-tsc --noEmit type-checks the Vue + TypeScript source without producing output — it catches type errors the dev server's HMR happily ignores. npm run web:build produces the production web bundle and surfaces build-time failures (bad imports, broken asset references) that only show up in a real build.
The preweb:build npm hook runs scripts/sync_ui_version.py first, so npm run web:build also confirms the version sync is wired correctly. See Versioning.
PR CI
The same commands run on every PR via .github/workflows/pr.yml. The workflow runs three jobs in parallel, and all three must pass before a PR can merge:
| Job | What it does |
|---|---|
backend | Runs uv run pytest. |
ui | Runs vue-tsc --noEmit plus the npm run web:build web smoke. |
smoke-build | Builds the Python wheel and a Linux Electron .AppImage, uploaded as PR artifacts so reviewers can install and try the build. |
A failing job blocks merge. The smoke-build artifacts are especially useful for reviewers: they can download the AppImage from the PR and run your change without checking out the branch.
Tips
- Run
uv run pytestwith a path or-kfilter while iterating — for exampleuv run pytest tests/storage -k upgrade— and run the full suite once before pushing. - If the
uijob fails but the dev server worked, it's almost always a type error that onlyvue-tsc --noEmitsurfaces. Run it locally to see the exact line. - Schema-touching PRs need an extra step beyond these three checks — see Schema migrations for testing an upgrade from a real older install, not just a fresh DB.