Phase A1: bootstrap Python ci_orchestrator package

- pyproject.toml (hatchling) with ruff/mypy/pytest dev deps
- src/ci_orchestrator/: config, credentials, backends (Protocol + WorkstationVmrunBackend), transport (WinRM via pypsrp, SSH via paramiko)
- CLI entry point with PoC 'wait-ready' subcommand (Windows + Linux guests)
- tests/python/: 35 unit tests, 83% coverage, all backends/transport mocked
- gitea/workflows/lint.yml: new 'python' job (ruff + mypy --strict + pytest --cov-fail-under=70)
- config.example.toml + README setup section + .gitignore Python entries

Neutral VmBackend Protocol prepared for Phase C ESXi extension.
See plans/implementation-plan-A-B.md step A1.
This commit is contained in:
2026-05-13 11:25:07 +02:00
parent 4d957d34b2
commit bd31a3f2f3
26 changed files with 1920 additions and 2 deletions
+36
View File
@@ -0,0 +1,36 @@
"""Factory test: load_backend dispatches on config.backend.type."""
from __future__ import annotations
from dataclasses import dataclass
from pathlib import Path
import pytest
from ci_orchestrator.backends import load_backend
from ci_orchestrator.backends.workstation import WorkstationVmrunBackend
@dataclass
class _BE:
type: str
@dataclass
class _Cfg:
backend: _BE
vmrun_path: str | None = None
def test_load_backend_returns_workstation(tmp_path: Path) -> None:
fake = tmp_path / "vmrun.exe"
fake.write_bytes(b"")
backend = load_backend(_Cfg(backend=_BE("workstation"), vmrun_path=str(fake)))
assert isinstance(backend, WorkstationVmrunBackend)
def test_load_backend_rejects_unknown(tmp_path: Path) -> None:
fake = tmp_path / "vmrun.exe"
fake.write_bytes(b"")
with pytest.raises(NotImplementedError):
load_backend(_Cfg(backend=_BE("esxi"), vmrun_path=str(fake)))