diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..27b889b --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,31 @@ +name: test + +# Runs the linter and the full pytest suite for visibility on every push and PR. +# Dogfoods the repo's own mise tasks: `mise run verify` == lint (ruff) then test (pytest), +# the same `verify` task the control layer's Stop hook enforces on managed projects. + +on: + push: + branches: ["**"] + tags: ["v*"] + pull_request: + branches: [main] + +jobs: + verify: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + # Installs the toolchain pinned in .mise.toml (Python 3.11). + - name: Set up mise + uses: jdx/mise-action@v2 + + # Dev extras carry pytest + respx + ruff; the package itself is installed editable so + # `pythonpath = ["src"]` in pyproject resolves the `handler` package under test. + - name: Install dependencies + run: pip install -e '.[dev]' + + - name: Lint and test + run: mise run verify diff --git a/tests/conftest.py b/tests/conftest.py index bf3fdb8..d8d9ed9 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -33,6 +33,12 @@ def env(tmp_path, monkeypatch): monkeypatch.setenv("SHARED_CONTEXT_WRITE_TOKEN", "shared-token") monkeypatch.setenv("PROJECTS_ROOT", str(tmp_path / "projects")) monkeypatch.delenv("WEBHOOK_URL", raising=False) + # Keep the fixture hermetic: when the suite runs inside a Handler-managed container + # (dogfooding), these are set in the ambient env and would leak into tests that assert + # the *unset* behavior — e.g. secretstore refusing without a key, or login using the + # default `claude` binary. Clear them so behavior is driven by each test, not the host. + monkeypatch.delenv("HANDLER_SECRET_KEY", raising=False) + monkeypatch.delenv("CLAUDE_BIN", raising=False) _reset_caches() cfg = Config(str(REPO_ROOT / "alembic.ini"))