From 7f3e3258cc32074a03a46b5e77fb5fedad8a620f Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 2 Jun 2026 13:18:19 +0000 Subject: [PATCH 1/2] ci: add Python pytest matrix and Rust cargo test workflows MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Closes #97. The repo ships a full Python mapper (canonical PyPI package) and an optional Rust acceleration crate, but CI only ran Node. The 29 Python tests and 3 PyO3 parity tests were never executed on push/PR, and publish-pypi.yml could ship a broken wheel because it did not run pytest before building. Add `.github/workflows/python-ci.yml` with two jobs: - `python-tests` — pytest across the Python 3.10 / 3.11 / 3.12 matrix on Ubuntu, against `pip install -e ".[dev]"`. Sets a CI git identity so the test_cli fixture commits work without per-developer git config. - `rust-tests` — `cargo test --release` against `rust/Cargo.toml`, then `maturin develop` + `pytest tests/python/test_native.py` so the native acceleration shim is exercised end-to-end (not just the pure-Python fallback). Wire the publish-pypi workflow to run pytest before `python -m build`, so a broken Python release can no longer ship to PyPI. https://claude.ai/code/session_01JdmemqddwFnvbceWyuDE8m --- .github/workflows/publish-pypi.yml | 15 +++++ .github/workflows/python-ci.yml | 90 ++++++++++++++++++++++++++++++ 2 files changed, 105 insertions(+) create mode 100644 .github/workflows/python-ci.yml diff --git a/.github/workflows/publish-pypi.yml b/.github/workflows/publish-pypi.yml index 6b73be8..b8d693a 100644 --- a/.github/workflows/publish-pypi.yml +++ b/.github/workflows/publish-pypi.yml @@ -70,6 +70,21 @@ jobs: run: | echo "::notice::Versão ${{ steps.meta.outputs.local }} já publicada no PyPI. Skipping." + - name: Configure Git identity (for fixture commits) + if: steps.meta.outputs.should_publish == 'true' + run: | + git config --global user.email "ci@simplicio.dev" + git config --global user.name "Simplicio CI" + git config --global commit.gpgsign false + + - name: Install package and dev deps + if: steps.meta.outputs.should_publish == 'true' + run: python -m pip install -e ".[dev]" + + - name: Run pytest before publishing + if: steps.meta.outputs.should_publish == 'true' + run: python -m pytest tests/python -q + - name: Build distributions if: steps.meta.outputs.should_publish == 'true' run: python -m build diff --git a/.github/workflows/python-ci.yml b/.github/workflows/python-ci.yml new file mode 100644 index 0000000..2dcb45d --- /dev/null +++ b/.github/workflows/python-ci.yml @@ -0,0 +1,90 @@ +# Python + Rust CI — pytest matrix for the Python package + cargo test +# (and a maturin build smoke check) for the optional Rust acceleration crate. +# Complements scaffold-self-check.yml (Node) and python-lint.yml (ruff). + +name: Python + Rust CI + +on: + push: + branches: + - main + - develop + pull_request: + branches: + - main + - develop + +concurrency: + group: python-rust-${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +permissions: + contents: read + +jobs: + python-tests: + name: pytest (Python ${{ matrix.python-version }}) + runs-on: ubuntu-latest + timeout-minutes: 10 + strategy: + fail-fast: false + matrix: + python-version: ['3.10', '3.11', '3.12'] + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Configure Git identity (for fixture commits) + run: | + git config --global user.email "ci@simplicio.dev" + git config --global user.name "Simplicio CI" + git config --global commit.gpgsign false + + - name: Setup Python ${{ matrix.python-version }} + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python-version }} + + - name: Install package and dev deps + run: | + python -m pip install --upgrade pip + python -m pip install -e ".[dev]" + + - name: Run pytest + run: python -m pytest tests/python -q + + rust-tests: + name: cargo test (PyO3 crate) + runs-on: ubuntu-latest + timeout-minutes: 15 + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Install Rust toolchain + uses: dtolnay/rust-toolchain@stable + + - name: Cache cargo target + uses: actions/cache@v4 + with: + path: | + ~/.cargo/registry + ~/.cargo/git + rust/target + key: cargo-${{ runner.os }}-${{ hashFiles('rust/Cargo.toml') }} + + - name: cargo test + run: cargo test --manifest-path rust/Cargo.toml --release + + - name: Setup Python + uses: actions/setup-python@v5 + with: + python-version: '3.11' + + - name: maturin develop + native parity test + run: | + python -m pip install --upgrade pip + python -m pip install maturin + python -m pip install -e ".[dev]" + (cd rust && maturin develop --release) + python -m pytest tests/python/test_native.py -q From f4b7eeb8b3c3b44f7379d427b2981735868fe91b Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 2 Jun 2026 13:20:34 +0000 Subject: [PATCH 2/2] ci: decouple python-ci from the dev extra and give maturin a venv The first run of #107 surfaced two issues: 1. `pip install -e ".[dev]"` warned `does not provide the extra 'dev'` because the dev extra ships in #105, which has not landed yet, so pytest was never installed and the matrix failed with `No module named pytest`. 2. `maturin develop` aborted with "Couldn't find a virtualenv" because the GitHub-hosted Python environment is not a venv. Fix: - Replace `.[dev]` with explicit `pip install pytest` (and `-e .`) in python-ci.yml and the publish-pypi.yml pre-publish step. The dev extra is a contributor convenience; CI does not need it. - Wrap the maturin step in a fresh `python -m venv .venv` + `source activate` so maturin has somewhere to install the editable extension. https://claude.ai/code/session_01JdmemqddwFnvbceWyuDE8m --- .github/workflows/publish-pypi.yml | 6 ++++-- .github/workflows/python-ci.yml | 10 ++++++---- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/.github/workflows/publish-pypi.yml b/.github/workflows/publish-pypi.yml index b8d693a..08754db 100644 --- a/.github/workflows/publish-pypi.yml +++ b/.github/workflows/publish-pypi.yml @@ -77,9 +77,11 @@ jobs: git config --global user.name "Simplicio CI" git config --global commit.gpgsign false - - name: Install package and dev deps + - name: Install package and pytest if: steps.meta.outputs.should_publish == 'true' - run: python -m pip install -e ".[dev]" + run: | + python -m pip install -e . + python -m pip install pytest - name: Run pytest before publishing if: steps.meta.outputs.should_publish == 'true' diff --git a/.github/workflows/python-ci.yml b/.github/workflows/python-ci.yml index 2dcb45d..b466b30 100644 --- a/.github/workflows/python-ci.yml +++ b/.github/workflows/python-ci.yml @@ -45,10 +45,11 @@ jobs: with: python-version: ${{ matrix.python-version }} - - name: Install package and dev deps + - name: Install package and pytest run: | python -m pip install --upgrade pip - python -m pip install -e ".[dev]" + python -m pip install -e . + python -m pip install pytest - name: Run pytest run: python -m pytest tests/python -q @@ -83,8 +84,9 @@ jobs: - name: maturin develop + native parity test run: | + python -m venv .venv + source .venv/bin/activate python -m pip install --upgrade pip - python -m pip install maturin - python -m pip install -e ".[dev]" + python -m pip install -e . maturin pytest (cd rust && maturin develop --release) python -m pytest tests/python/test_native.py -q