Skip to content

Commit 5a13bac

Browse files
njbrakeclaude
andcommitted
Add PR CI and make control-plane integration tests skip without a gateway
- Add .github/workflows/ci.yml: ruff + mypy + pytest on push/PR across Python 3.11-3.13 (the repo previously only ran checks on release). - Integration tests skip cleanly when no gateway is on PATH (set OTARI_GATEWAY_CMD to run them), so CI is green without a gateway and passes with one. - Register the 'integration' marker; per-file-ignore the subprocess/URL audit rules for the test harness. Part of mozilla-ai/otari#96 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 1664bff commit 5a13bac

3 files changed

Lines changed: 48 additions & 1 deletion

File tree

.github/workflows/ci.yml

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [main]
6+
pull_request:
7+
branches: [main]
8+
workflow_dispatch:
9+
10+
permissions:
11+
contents: read
12+
13+
jobs:
14+
test:
15+
runs-on: ubuntu-latest
16+
strategy:
17+
matrix:
18+
python-version: ["3.11", "3.12", "3.13"]
19+
steps:
20+
- uses: actions/checkout@v4
21+
22+
- uses: astral-sh/setup-uv@v6
23+
with:
24+
python-version: ${{ matrix.python-version }}
25+
26+
- name: Install dependencies
27+
run: uv sync --extra dev
28+
29+
- name: Lint
30+
run: uv run ruff check .
31+
32+
- name: Type check
33+
run: uv run mypy src/
34+
35+
- name: Test
36+
# Integration tests skip automatically when no gateway is on PATH.
37+
run: uv run pytest

pyproject.toml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,9 @@ packages = ["src/otari"]
5050
[tool.pytest.ini_options]
5151
testpaths = ["tests"]
5252
asyncio_mode = "auto"
53+
markers = [
54+
"integration: tests that require a running gateway (skipped if none is available)",
55+
]
5356

5457
[tool.ruff]
5558
target-version = "py311"
@@ -61,6 +64,11 @@ extend-exclude = ["src/otari/_control_plane"]
6164
select = ["E", "F", "I", "N", "W", "UP", "S", "B", "A", "C4", "DTZ", "T10", "ISC", "ICN", "PIE", "PT", "RSE", "RET", "SIM", "TID", "TCH", "ARG", "PLC", "PLE", "PLW", "TRY", "FLY", "PERF", "RUF"]
6265
ignore = ["S101", "TRY003", "PLW0603"]
6366

67+
[tool.ruff.lint.per-file-ignores]
68+
# Integration tests spawn the gateway subprocess and poll it over HTTP; the
69+
# subprocess/URL/temp-file audit rules don't apply to that test harness.
70+
"tests/integration/*" = ["S603", "S310", "SIM115", "SIM117", "PLC0415", "TC003"]
71+
6472
[tool.ruff.lint.isort]
6573
known-first-party = ["otari"]
6674

tests/integration/test_control_plane_generated.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,14 @@
1919

2020
import contextlib
2121
import os
22+
import shutil
2223
import socket
2324
import subprocess
2425
import tempfile
2526
import time
2627
import urllib.error
2728
import urllib.request
2829
from collections.abc import Iterator
29-
from pathlib import Path
3030

3131
import pytest
3232

@@ -65,6 +65,8 @@ def _wait_healthy(base_url: str, timeout: float = 30.0) -> None:
6565
@pytest.fixture(scope="module")
6666
def gateway_url() -> Iterator[str]:
6767
cmd = os.environ.get("OTARI_GATEWAY_CMD", "gateway").split()
68+
if shutil.which(cmd[0]) is None:
69+
pytest.skip(f"gateway command '{cmd[0]}' not found; set OTARI_GATEWAY_CMD (e.g. pip install the gateway)")
6870
port = _free_port()
6971
db_path = tempfile.NamedTemporaryFile(suffix=".db", delete=False).name
7072
proc = subprocess.Popen(

0 commit comments

Comments
 (0)