Repository navigation
Build 0.3.35 Windows runtime wheels with MTMD fix #39
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: tests | |
| on: | |
| push: | |
| branches: [main] | |
| pull_request: | |
| jobs: | |
| release-metadata: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: '3.12' | |
| - run: python -m pip install pytest build | |
| - name: Test release verification without network or publishing | |
| run: python -m pytest tests/test_release_metadata.py | |
| - name: Check distribution contents | |
| run: | | |
| python -m build | |
| python - <<'PY' | |
| from pathlib import Path | |
| import subprocess | |
| import tarfile | |
| import tomllib | |
| import zipfile | |
| version = tomllib.loads(Path("pyproject.toml").read_text())["project"]["version"] | |
| runtime = set(subprocess.check_output( | |
| ["git", "ls-files", "-z", "programasweights"], text=True, | |
| ).split("\0")) - {""} | |
| def check(actual, expected): | |
| assert actual == expected, ( | |
| f"Unexpected files: {sorted(actual - expected)}; " | |
| f"missing files: {sorted(expected - actual)}" | |
| ) | |
| wheel, = Path("dist").glob("*.whl") | |
| metadata = { | |
| f"programasweights-{version}.dist-info/{name}" | |
| for name in ( | |
| "METADATA", "WHEEL", "RECORD", | |
| "entry_points.txt", "licenses/LICENSE", | |
| ) | |
| } | |
| with zipfile.ZipFile(wheel) as archive: | |
| check({name for name in archive.namelist() if not name.endswith("/")}, | |
| runtime | metadata) | |
| sdist, = Path("dist").glob("*.tar.gz") | |
| allowed = runtime | { | |
| "README.md", "PYPI_README.md", "LICENSE", "CHANGELOG.md", | |
| "pyproject.toml", ".gitignore", "PKG-INFO", | |
| } | |
| with tarfile.open(sdist) as archive: | |
| check({member.name for member in archive if not member.isdir()}, | |
| {f"programasweights-{version}/{name}" for name in allowed}) | |
| PY | |
| test: | |
| runs-on: ubuntu-24.04 | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| python-version: ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13", "3.14"] | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Set up Python ${{ matrix.python-version }} | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: ${{ matrix.python-version }} | |
| - name: Install (hermetic deps only) | |
| # Install httpx + pytest and the package itself without pulling the heavy | |
| # llama-cpp-python build. Runtime tests inject a fake llama_cpp module, | |
| # so CI needs neither the native extension nor a model download. | |
| run: | | |
| python -m pip install --upgrade pip | |
| python -m pip install httpx pytest | |
| python -m pip install -e . --no-deps | |
| - name: Run hermetic tests | |
| # Scoped to tests that need no network, no model download, and no | |
| # PAW_API_KEY. Auth tests (@needs_auth) auto-skip without a key; the | |
| # network/model-download tests in test_sdk.py are excluded here and can | |
| # be run separately against a live server. | |
| run: | | |
| pytest \ | |
| tests/test_api_errors.py \ | |
| tests/test_compile_timeouts.py \ | |
| tests/test_local_program.py \ | |
| tests/test_base_interpreter.py \ | |
| tests/test_cli_auth.py \ | |
| tests/test_remote_inference.py \ | |
| tests/test_desktop_sdk.py \ | |
| tests/test_runtime_registry_sdk.py \ | |
| tests/test_sdk.py::TestInstallAndImport | |
| local-files-windows: | |
| runs-on: windows-latest | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| python-version: ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13", "3.14"] | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: ${{ matrix.python-version }} | |
| - name: Install hermetic test dependencies | |
| run: | | |
| python -m pip install httpx pytest | |
| python -m pip install -e . --no-deps | |
| - name: Test Windows local paths, cache locks, and compile errors | |
| run: python -m pytest tests/test_api_errors.py tests/test_compile_timeouts.py tests/test_local_program.py tests/test_remote_inference.py --junitxml=test-results.xml | |
| - name: Annotate Windows test failures | |
| if: failure() | |
| shell: python | |
| run: | | |
| from pathlib import Path | |
| import xml.etree.ElementTree as ET | |
| report = Path("test-results.xml") | |
| if report.exists(): | |
| for case in ET.parse(report).iter("testcase"): | |
| for result in case: | |
| if result.tag in {"failure", "error"}: | |
| # GitHub truncates annotations, so retain the actual | |
| # exception at the end of long pytest tracebacks. | |
| detail = result.text or result.get("message", "") | |
| message = f"{case.get('name')}: {detail[-3500:]}" | |
| message = message.replace("%", "%25").replace("\r", "%0D").replace("\n", "%0A") | |
| print(f"::error::{message}") | |
| native-install: | |
| runs-on: ${{ matrix.platform.runner }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| python-version: ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13", "3.14"] | |
| platform: | |
| - {runner: ubuntu-24.04, arch: x64} | |
| - {runner: windows-2022, arch: x64} | |
| - {runner: macos-15, arch: arm64} | |
| - {runner: macos-15-intel, arch: x64} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: ${{ matrix.python-version }} | |
| architecture: ${{ matrix.platform.arch }} | |
| - name: Install SDK wheel and load its native dependency | |
| env: | |
| EXPECTED_ARCH: ${{ matrix.platform.arch }} | |
| shell: python | |
| run: | | |
| import os, platform, subprocess, sys, venv | |
| from pathlib import Path | |
| architectures = {"x64": {"x86_64", "amd64"}, "arm64": {"arm64", "aarch64"}} | |
| assert platform.machine().lower() in architectures[os.environ["EXPECTED_ARCH"]] | |
| root = Path(os.environ["RUNNER_TEMP"]) / "paw-native" | |
| venv.create(root, with_pip=True) | |
| python = root / ("Scripts/python.exe" if sys.platform == "win32" else "bin/python") | |
| def run(*args): | |
| subprocess.run([str(python), *args], check=True) | |
| run("-m", "pip", "install", "--upgrade", "pip") | |
| run("-m", "pip", "wheel", "--no-deps", "--wheel-dir", str(root / "dist"), ".") | |
| wheel, = (root / "dist").glob("*.whl") | |
| run("-m", "pip", "install", str(wheel), "--extra-index-url", | |
| "https://pypi.programasweights.com/simple/", "--only-binary=llama-cpp-python") | |
| run("-m", "pip", "check") | |
| run("-I", "-c", "import programasweights, llama_cpp; " | |
| "print(programasweights.__version__, llama_cpp.__version__); " | |
| "print(llama_cpp.llama_print_system_info().decode())") |