# Continuous integration

This document describes what runs in GitHub Actions and how it relates to local `pytest` ([`pytest.ini`](../pytest.ini)). Required PR gates run the **unit** tree only; a bare `pytest` from the repo root follows `pytest.ini` and discovers the full **`backend/tests`** tree (slower, may need services).

## Required checks on pull requests

| Workflow | Job | What runs |
|----------|-----|-----------|
| **Run Python Tests** | `gates-on-linux` | Full unit corpus: `pytest backend/tests/unit` (required PR gates; narrower than a bare local `pytest`, which uses `testpaths = backend/tests` in [`pytest.ini`](../pytest.ini)). |
| **Run Python Tests** | `gates-on-windows` | Same unit corpus as `gates-on-linux` on `windows-latest`. |
| **Run Python Tests** | `gates-on-macos` | Same unit corpus as `gates-on-linux` on `macos-latest` — **advisory only** (`continue-on-error: true`) until the matrix is promoted to required. |
| **Lint** | pre-commit, mypy, version check | See [`.github/workflows/lint.yml`](../.github/workflows/lint.yml). |
| **Dependency Review** | `dependency-review` | Blocks high-severity dependency risk on pull requests. |
| **CodeQL** | `analyze` | Static security analysis for Python on PRs and main. |
| **CLI Regression Tests** | (when paths match) | CLI integration smoke and selected orchestration tests; see [`.github/workflows/e2e-tests.yml`](../.github/workflows/e2e-tests.yml). |

Codecov upload is enforced (`fail_ci_if_error: true`) and coverage uses the same `fail_under` policy as the project configuration.

## Heavy / integration / benchmark tier

The **Heavy / Integration Tests** job in `py-tests.yml` runs only when:

- the workflow is scheduled,
- manually dispatched, or
- the push is to `main`.

It executes: `pytest backend/tests -m "heavy or integration or benchmark"`.

Markers are defined in `pytest.ini`. That job is marker-filtered over the full tree. A bare local `pytest` (no path arguments) still collects all of `backend/tests` per `testpaths`; narrow with `pytest backend/tests/unit` or add `-m` when you want a smaller slice.

## What to run before opening a PR

See [Contributing — testing](../CONTRIBUTING.md#testing-before-a-pull-request).

## Support stance for announcement copy

For public release messaging, align claims with [Support Matrix](SUPPORT_MATRIX.md):

- Linux and Windows are officially supported (required CI gates).
- macOS is best-effort until promoted from advisory to required.
