Skip to content

Commit aedaf28

Browse files
ci: align ruff tooling and add CI workflow (#6)
* ci: align ruff tooling and add CI workflow The .pre-commit-config.yaml was pinning ruff v0.5.0 (mid-2024) while the dev-dep ruff resolved to v0.15.11. The two versions disagree on isort grouping (newer ruff splits pydantic and openarmature into separate import groups; v0.5.0 merges them), which caused test files to ping-pong between forms on every commit cycle. Bump pre-commit ruff to v0.15.11 to match the dev dep, then run `ruff check --fix` once to settle the disagreement on the newer form. Eight test-file imports reordered as a result. Add `.github/workflows/ci.yml` running: - Checkout with submodules (the openarmature-spec submodule carries the conformance fixtures) - uv sync --frozen - ruff check - ruff format --check - pyright src/ tests/ - pytest -q Same checks the pre-commit hook runs locally, now also enforced server-side so PRs from contributors who haven't installed pre-commit don't bypass them. Concurrency group cancels in-flight runs on the same ref. * ci: add explicit permissions block for least-privilege Mirrors LunarCommand/openarmature-examples#3: pin GITHUB_TOKEN to `contents: read`. The workflow only needs to checkout code + the spec submodule; no writes. * ci: apply v0.15.11 ordering to files added since rebase base Post-rebase: ruff v0.15.11 splits pydantic and openarmature into separate import groups, where v0.5.0 (the version on main when #5 landed) merged them. The bumped pre-commit hook in this branch applies the new ordering to test files brought in by #5. * ci: drop explicit Python install, use .python-version Per PR #6 review: the workflow had `uv python install 3.12` while .python-version pins 3.14, creating a CI/dev skew where CI could end up testing a different interpreter than developers run locally. Drop the explicit install step. uv sync auto-provisions whatever .python-version pins, keeping CI and dev aligned. requires-python ">=3.12" in pyproject.toml still establishes 3.12 as the floor; testing the floor specifically is a separate concern (matrix build) we can add later if needed.
1 parent 75740a9 commit aedaf28

10 files changed

Lines changed: 72 additions & 13 deletions

.github/workflows/ci.yml

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
name: CI
2+
3+
on:
4+
pull_request:
5+
branches: [main]
6+
push:
7+
branches: [main]
8+
9+
# Least-privilege: the workflow only needs to read code (checkout +
10+
# submodule). No writes anywhere.
11+
permissions:
12+
contents: read
13+
14+
# Cancel in-flight runs on the same ref when a new push lands.
15+
concurrency:
16+
group: ${{ github.workflow }}-${{ github.ref }}
17+
cancel-in-progress: true
18+
19+
jobs:
20+
test:
21+
runs-on: ubuntu-latest
22+
steps:
23+
- name: Checkout
24+
uses: actions/checkout@v4
25+
with:
26+
# Conformance fixtures live in the openarmature-spec submodule.
27+
submodules: recursive
28+
29+
- name: Install uv
30+
uses: astral-sh/setup-uv@v4
31+
with:
32+
enable-cache: true
33+
34+
# No explicit `uv python install` — `uv sync` auto-provisions the
35+
# interpreter pinned in `.python-version`, so CI tests the same
36+
# version developers run locally.
37+
38+
- name: Sync deps
39+
run: uv sync --frozen
40+
41+
- name: Lint (ruff check)
42+
run: uv run ruff check .
43+
44+
- name: Format check (ruff format --check)
45+
run: uv run ruff format --check .
46+
47+
- name: Type check (pyright)
48+
run: uv run pyright src/ tests/
49+
50+
- name: Run tests (pytest)
51+
run: uv run pytest -q

.pre-commit-config.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ repos:
1010
- id: check-added-large-files
1111

1212
- repo: https://github.com/astral-sh/ruff-pre-commit
13-
rev: v0.5.0
13+
rev: v0.15.11
1414
hooks:
1515
- id: ruff
1616
args: [--fix]

tests/conformance/adapter.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
from dataclasses import dataclass, field
1616
from typing import TYPE_CHECKING, Annotated, Any, cast
1717

18+
from pydantic import Field, create_model
19+
1820
from openarmature.graph import (
1921
END,
2022
CompiledGraph,
@@ -32,7 +34,6 @@
3234
)
3335
from openarmature.graph.events import NodeEvent
3436
from openarmature.graph.observer import Observer
35-
from pydantic import Field, create_model
3637

3738
if TYPE_CHECKING:
3839
from openarmature.graph.observer import _InvocationContext

tests/conformance/test_conformance.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
import pytest
1414
import yaml
15+
1516
from openarmature.graph import (
1617
CompileError,
1718
NodeException,
@@ -139,15 +140,15 @@ async def test_runtime_fixture(fixture_path: Path) -> None:
139140
for name, expected_events in expected["observer_events"].items():
140141
actual = observer_fixtures[name].events
141142
normalized = [normalize_expected_event(ev) for ev in expected_events]
142-
assert (
143-
actual == normalized
144-
), f"observer events mismatch for {name!r}: actual={actual}, expected={normalized}"
143+
assert actual == normalized, (
144+
f"observer events mismatch for {name!r}: actual={actual}, expected={normalized}"
145+
)
145146

146147
if "delivery_order" in expected:
147148
expected_delivery = [(d["observer"], d["step"]) for d in expected["delivery_order"]]
148-
assert (
149-
delivery == expected_delivery
150-
), f"delivery_order mismatch: actual={delivery}, expected={expected_delivery}"
149+
assert delivery == expected_delivery, (
150+
f"delivery_order mismatch: actual={delivery}, expected={expected_delivery}"
151+
)
151152

152153

153154
# ---------------------------------------------------------------------------

tests/unit/test_compile_errors.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
from typing import Any
44

55
import pytest
6+
67
from openarmature.graph import (
78
END,
89
DanglingEdge,

tests/unit/test_generics.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111

1212
from typing import Annotated, Any, assert_type
1313

14+
from pydantic import Field
15+
1416
from openarmature.graph import (
1517
END,
1618
CompiledGraph,
@@ -20,7 +22,6 @@
2022
State,
2123
append,
2224
)
23-
from pydantic import Field
2425

2526

2627
class ParentS(State):

tests/unit/test_projection.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
"""Projection strategy unit coverage: FieldNameMatching + ExplicitMapping."""
22

33
import pytest
4+
from pydantic import Field
5+
46
from openarmature.graph import (
57
ExplicitMapping,
68
FieldNameMatching,
79
MappingReferencesUndeclaredField,
810
State,
911
)
10-
from pydantic import Field
1112

1213

1314
class Parent(State):

tests/unit/test_runtime_errors.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
from typing import Annotated, Any
1111

1212
import pytest
13+
from pydantic import Field
14+
1315
from openarmature.graph import (
1416
END,
1517
EdgeException,
@@ -20,7 +22,6 @@
2022
StateValidationError,
2123
append,
2224
)
23-
from pydantic import Field
2425

2526

2627
class S(State):

tests/unit/test_state_and_reducers.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,10 @@
33
from typing import Annotated
44

55
import pytest
6+
from pydantic import Field, ValidationError
7+
68
from openarmature.graph import END, State, append, last_write_wins, merge
79
from openarmature.graph.state import field_reducers, resolve_reducer
8-
from pydantic import Field, ValidationError
910

1011

1112
class S(State):

tests/unit/test_subgraph.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88

99
from typing import Annotated, Any
1010

11+
from pydantic import Field
12+
1113
from openarmature.graph import (
1214
END,
1315
FieldNameMatching,
@@ -16,7 +18,6 @@
1618
SubgraphNode,
1719
append,
1820
)
19-
from pydantic import Field
2021

2122

2223
class Inner(State):

0 commit comments

Comments
 (0)