name: CI on: pull_request: push: branches: - main permissions: contents: read concurrency: group: ci-${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true env: PIP_DISABLE_PIP_VERSION_CHECK: "1" PIP_NO_INPUT: "1" jobs: package: name: Package runs-on: ubuntu-latest timeout-minutes: 15 steps: - name: Check out repository uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Set up Python uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 with: python-version: "3.12" cache: pip cache-dependency-path: | pyproject.toml requirements*.txt - name: Install build tooling run: python -m pip install "build==1.2.2.post1" - name: Build source and wheel distributions run: python -m build --sdist --wheel - name: Verify wheel contents and entry point run: | python - <<'PY' from pathlib import Path from zipfile import ZipFile wheels = list(Path("dist").glob("*.whl")) if len(wheels) != 1: raise SystemExit(f"expected one wheel, found: {wheels}") with ZipFile(wheels[0]) as archive: names = set(archive.namelist()) required = { "app.py", "obliteratus/__init__.py", "obliteratus/local_ui.py", } missing = sorted(required - names) if missing: raise SystemExit(f"wheel is missing required modules: {missing}") entry_points = [ name for name in names if name.endswith(".dist-info/entry_points.txt") ] if len(entry_points) != 1: raise SystemExit(f"expected one entry_points.txt, found: {entry_points}") contents = archive.read(entry_points[0]).decode("utf-8") if "obliteratus = obliteratus.cli:main" not in contents: raise SystemExit("wheel is missing the obliteratus console entry point") print(f"verified wheel contents: {wheels[0]}") PY lint: name: Ruff runs-on: ubuntu-latest timeout-minutes: 15 steps: - name: Check out repository uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Set up Python uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 with: python-version: "3.12" cache: pip cache-dependency-path: pyproject.toml - name: Install Ruff run: python -m pip install "ruff==0.8.6" - name: Enforce Ruff F gate run: python -m ruff check --select F obliteratus tests scripts/gemma4_12b_recursive_loop.py - name: Report E501 legacy baseline if: always() run: python -m ruff check --select E501 --statistics obliteratus tests scripts/gemma4_12b_recursive_loop.py || true test: name: Tests py${{ matrix.python-version }} runs-on: ubuntu-latest timeout-minutes: 45 strategy: fail-fast: false matrix: python-version: - "3.10" - "3.11" - "3.12" steps: - name: Check out repository uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Set up Python uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 with: python-version: ${{ matrix.python-version }} cache: pip cache-dependency-path: | pyproject.toml requirements*.txt - name: Install CPU PyTorch run: python -m pip install --index-url https://download.pytorch.org/whl/cpu "torch>=2.0" - name: Install package and test tools run: | python - <<'PY' > /tmp/torch-cpu-constraint.txt import torch print(f"torch=={torch.__version__}") PY python -m pip install -e ".[dev]" -c /tmp/torch-cpu-constraint.txt - name: Smoke import and CLI run: | python - <<'PY' import obliteratus version = getattr(obliteratus, "__version__", None) if version is not None: print(f"obliteratus version: {version}") else: print("obliteratus import: ok") PY python -m obliteratus --help - name: Run tests with coverage run: python -m pytest