11name : CI
22
3+ # Action SHAs are pinned, not floating tags. To bump:
4+ # gh api repos/<owner>/<repo>/commits/<tag> --jq .sha
5+ # (use /commits/<tag>, NOT /git/refs/tags/<tag> — annotated tags would
6+ # return the tag-object SHA, which Actions can't resolve.)
7+ # Update the comment on the right with the new tag for traceability.
8+
39on :
410 push :
511 branches : [develop, main]
@@ -19,3 +25,104 @@ jobs:
1925 - run : uv sync --frozen --extra dev
2026 - run : uv run ruff check .
2127 - run : uv run ruff format --check .
28+
29+ typecheck :
30+ name : Type Check
31+ runs-on : ubuntu-latest
32+ steps :
33+ - uses : actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
34+ - uses : astral-sh/setup-uv@cec208311dfd045dd5311c1add060b2062131d57 # v8
35+ - uses : actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
36+ with :
37+ python-version : " 3.14"
38+ - run : uv sync --frozen --extra dev
39+ - run : uv run mypy --strict src/ tests/
40+
41+ test-unit :
42+ name : Unit tests
43+ runs-on : ubuntu-latest
44+ # Pure in-process tests — completes fast so PR authors get quick feedback.
45+ steps :
46+ - uses : actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
47+ - uses : astral-sh/setup-uv@cec208311dfd045dd5311c1add060b2062131d57 # v8
48+ - uses : actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
49+ with :
50+ python-version : " 3.14"
51+ - run : uv sync --frozen --extra dev
52+ - run : uv run pytest tests/ -v -m "not integration" -o "addopts="
53+
54+ coverage :
55+ name : Coverage
56+ runs-on : ubuntu-latest
57+ # Runs the suite with coverage. Until ticket #17 lands real source under
58+ # src/, the template has no measurable coverage; pyproject.toml's
59+ # [tool.coverage.report].fail_under stays at 75 (the eventual target),
60+ # while CI uses --cov-fail-under=0 so the empty scaffold doesn't fail.
61+ # When #17 + #18 ship real source + tests, drop the override here.
62+ steps :
63+ - uses : actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
64+ - uses : astral-sh/setup-uv@cec208311dfd045dd5311c1add060b2062131d57 # v8
65+ - uses : actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
66+ with :
67+ python-version : " 3.14"
68+ - run : uv sync --frozen --extra dev
69+ - run : uv run pytest tests/ --cov=src --cov-report=term-missing --cov-fail-under=0
70+
71+ architecture :
72+ name : Architecture (import-linter)
73+ runs-on : ubuntu-latest
74+ steps :
75+ - uses : actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
76+ - uses : astral-sh/setup-uv@cec208311dfd045dd5311c1add060b2062131d57 # v8
77+ - uses : actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
78+ with :
79+ python-version : " 3.14"
80+ - run : uv sync --frozen --extra dev
81+ - run : uv run lint-imports
82+
83+ pre-commit :
84+ name : Pre-commit
85+ runs-on : ubuntu-latest
86+ # Runs every hook against all files — ensures a developer who forgot
87+ # `uv run pre-commit install` can't leak unformatted code or a stray
88+ # secret past the first defence layer.
89+ steps :
90+ - uses : actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
91+ - uses : astral-sh/setup-uv@cec208311dfd045dd5311c1add060b2062131d57 # v8
92+ - uses : actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
93+ with :
94+ python-version : " 3.14"
95+ - run : uv sync --frozen --extra dev
96+ - run : uv run pre-commit run --all-files --show-diff-on-failure
97+
98+ frontend-build :
99+ name : Frontend Build
100+ runs-on : ubuntu-latest
101+ # Skips cleanly until ticket #21 lands frontend/package.json.
102+ if : hashFiles('frontend/package.json') != ''
103+ steps :
104+ - uses : actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
105+ - uses : actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
106+ with :
107+ node-version : " 24"
108+ cache : npm
109+ cache-dependency-path : frontend/package-lock.json
110+ - run : cd frontend && npm ci && npm run build
111+
112+ frontend-quality :
113+ name : Frontend Quality
114+ runs-on : ubuntu-latest
115+ # Lint + format + tsc + vitest.
116+ if : hashFiles('frontend/package.json') != ''
117+ steps :
118+ - uses : actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
119+ - uses : actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
120+ with :
121+ node-version : " 24"
122+ cache : npm
123+ cache-dependency-path : frontend/package-lock.json
124+ - run : cd frontend && npm ci
125+ - run : cd frontend && npm run lint
126+ - run : cd frontend && npm run format:check
127+ - run : cd frontend && npm run check
128+ - run : cd frontend && npm run test
0 commit comments