Skip to content

feat(update): add app-notification delivery and main yaml version reader #108

feat(update): add app-notification delivery and main yaml version reader

feat(update): add app-notification delivery and main yaml version reader #108

name: CI - Python Bindings
on:
push:
branches: [main, classic-next, develop, classic-9.1]
pull_request:
branches: [main, classic-next, develop, classic-9.1]
env:
RUST_BACKTRACE: 1
CARGO_TERM_COLOR: always
jobs:
parity-gates:
name: Python Parity Gates
runs-on: windows-latest
timeout-minutes: 30
steps:
- uses: actions/checkout@v6
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: "3.12"
- name: Install uv
uses: astral-sh/setup-uv@v7
with:
enable-cache: true
cache-dependency-glob: python-bindings/uv.lock
- name: Run Python binding compliance profile
run: python tools/binding_compliance/check_compliance.py --repo-root . --profile python-ci
- name: Upload parity and runtime coverage diagnostics
if: failure()
uses: actions/upload-artifact@v6
with:
name: python-parity-diagnostics
path: |
tools/binding_compliance/artifacts/
python-bindings/parity-artifacts/
if-no-files-found: warn
retention-days: 7
build-and-test:
name: Python Bindings Build + Smoke Tests
needs: [parity-gates]
runs-on: windows-latest
timeout-minutes: 90
steps:
- uses: actions/checkout@v6
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: "3.12"
- name: Install uv
uses: astral-sh/setup-uv@v7
with:
enable-cache: true
cache-dependency-glob: python-bindings/uv.lock
- name: Cache cargo registry
uses: actions/cache@v5
with:
path: ~/.cargo/registry
key: ${{ runner.os }}-cargo-registry-${{ hashFiles('**/Cargo.lock') }}
restore-keys: |
${{ runner.os }}-cargo-registry-
- name: Cache cargo index
uses: actions/cache@v5
with:
path: ~/.cargo/git
key: ${{ runner.os }}-cargo-index-${{ hashFiles('**/Cargo.lock') }}
restore-keys: |
${{ runner.os }}-cargo-index-
- name: Cache cargo build
uses: actions/cache@v5
with:
path: target
key: ${{ runner.os }}-cargo-python-${{ hashFiles('**/Cargo.lock') }}-${{ hashFiles('foundation/**/*.rs', 'business-logic/**/*.rs', 'cpp-bindings/**/*.rs', 'node-bindings/**/*.rs', 'python-bindings/**/*.rs', 'ui-applications/**/*.rs') }}
restore-keys: |
${{ runner.os }}-cargo-python-${{ hashFiles('**/Cargo.lock') }}-
${{ runner.os }}-cargo-python-
# `uv sync` creates `python-bindings/.venv` and installs the locked
# tooling set (`maturin`, `pytest`). `--inexact` guards against the
# maturin-built `classic-*-py` wheels being pruned on any re-sync.
# `--locked` fails the job if the committed uv.lock drifts from
# pyproject.toml — catches silent lock/manifest divergence.
- name: Install Python bindings tooling
run: uv sync --project python-bindings --inexact --locked
# `maturin` is intentionally installed into `python-bindings/.venv` by
# the step above. `rebuild_rust.ps1` targets that interpreter explicitly
# for Python binding builds. Smoke-test collection imports promoted
# modules at import time, so CI must install the full Python binding
# set instead of a hand-maintained subset.
- name: Build and install Python bindings
shell: pwsh
run: pwsh -ExecutionPolicy Bypass -File rebuild_rust.ps1 -Target python
# Must invoke pytest through `python -m pytest`, not the `pytest.exe`
# entrypoint. `classic_config.ClassicConfig.get_config_path()` anchors
# settings discovery to `sys.argv[0]`'s parent directory (see
# test_config_import_anchors_settings_to_script_directory). When pytest
# runs as a console-script .exe, sys.argv[0] becomes `.venv\Scripts\pytest.exe`,
# which `get_config_path()` treats as a script path and derives a bogus
# settings parent from. `-m pytest` keeps sys.argv[0] pointed at the
# pytest package file, preserving the expected script-directory shape.
- name: Run Python bindings smoke tests
run: uv run --project python-bindings python -m pytest python-bindings/tests -q