name: Python
on:
push:
pull_request:
env:
PYTHON_VERSION: "3.14"
FLATC_VERSION: "25.12.19"
jobs:
lint:
name: Lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Install FlatBuffers compiler
run: |
curl -sL "https://github.com/google/flatbuffers/releases/download/v${{ env.FLATC_VERSION }}/Linux.flatc.binary.clang++-18.zip" -o flatc.zip
unzip -q flatc.zip
chmod +x flatc
sudo mv flatc /usr/local/bin/
- name: Install uv
uses: astral-sh/setup-uv@v7
- name: Set up Python
run: uv python install ${{ env.PYTHON_VERSION }}
- name: Check formatting with black
run: uvx black --check python/ benchmarks/
- name: Lint with flake8
run: uvx flake8 python/ benchmarks/
- name: Type check with mypy
run: uvx mypy python/rustling/
test:
name: Test
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"]
steps:
- uses: actions/checkout@v6
- name: Install FlatBuffers compiler
run: |
curl -sL "https://github.com/google/flatbuffers/releases/download/v${{ env.FLATC_VERSION }}/Linux.flatc.binary.clang++-18.zip" -o flatc.zip
unzip -q flatc.zip
chmod +x flatc
sudo mv flatc /usr/local/bin/
- name: Install uv
uses: astral-sh/setup-uv@v7
- name: Set up Python ${{ matrix.python-version }}
run: uv python install ${{ matrix.python-version }}
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
- name: Build and install package
run: |
uv venv
uv pip install maturin pytest
uv run maturin develop
- name: Run tests
env:
GH_TOKEN: ${{ secrets.GH_PAT }}
PRIVATE_TEST_REPO: ${{ secrets.PRIVATE_TEST_REPO }}
run: uv run pytest python/tests/ -v
- name: Verify stub files
if: matrix.python-version == '3.14'
run: uv run python -m mypy.stubtest rustling --concise --ignore-missing-stub --allowlist python/stubtest_allowlist.txt
audit:
name: Audit
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Install uv
uses: astral-sh/setup-uv@v7
- name: Audit dev dependencies
run: uv export --no-hashes --group dev | uvx pip-audit -r /dev/stdin --desc
sdist:
name: Build source distribution (release readiness check)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Build sdist
uses: PyO3/maturin-action@v1
with:
command: sdist
args: --out dist
wheels:
name: Build wheels on ${{ matrix.os }} (${{ matrix.target }}) (release readiness check)
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-latest
target: x86_64
- os: ubuntu-latest
target: aarch64
- os: macos-15-intel
target: x86_64
- os: macos-14
target: aarch64
- os: windows-latest
target: x86_64
steps:
- uses: actions/checkout@v6
- name: Install FlatBuffers compiler (macOS)
if: runner.os == 'macOS'
run: brew install flatbuffers
- name: Install FlatBuffers compiler (Windows)
if: runner.os == 'Windows'
shell: pwsh
run: |
$url = "https://github.com/google/flatbuffers/releases/download/v${{ env.FLATC_VERSION }}/Windows.flatc.binary.zip"
Invoke-WebRequest -Uri $url -OutFile flatc.zip
Expand-Archive -Path flatc.zip -DestinationPath flatc_bin
echo "$PWD\flatc_bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
- name: Build wheels
uses: PyO3/maturin-action@v1
with:
target: ${{ matrix.target }}
args: --release --out dist -i python3.10
sccache: "true"
manylinux: auto
before-script-linux: |
curl -sL "https://github.com/google/flatbuffers/releases/download/v${{ env.FLATC_VERSION }}/Linux.flatc.binary.clang++-18.zip" -o flatc.zip
command -v unzip || yum install -y unzip 2>/dev/null || (apt-get update -qq && apt-get install -y -qq unzip)
unzip -q flatc.zip
chmod +x flatc
mv flatc /usr/local/bin/
wasm-wheel:
name: Build wasm32-unknown-emscripten wheel (release readiness check)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Install FlatBuffers compiler
run: |
curl -sL "https://github.com/google/flatbuffers/releases/download/v${{ env.FLATC_VERSION }}/Linux.flatc.binary.clang++-18.zip" -o flatc.zip
unzip -q flatc.zip
chmod +x flatc
sudo mv flatc /usr/local/bin/
- name: Install Rust nightly
uses: dtolnay/rust-toolchain@master
with:
toolchain: nightly-2025-06-27
components: rust-src
- name: Install Emscripten wasm-eh sysroot
run: |
TOOLCHAIN_ROOT=$(rustup run nightly-2025-06-27 rustc --print sysroot)
RUSTLIB=$TOOLCHAIN_ROOT/lib/rustlib
curl -sL https://github.com/pyodide/rust-emscripten-wasm-eh-sysroot/releases/download/emcc-4.0.9_nightly-2025-06-27/emcc-4.0.9_nightly-2025-06-27.tar.bz2 -o emcc-4.0.9_nightly-2025-06-27.tar.bz2
tar -xf emcc-4.0.9_nightly-2025-06-27.tar.bz2 --directory=$RUSTLIB
- name: Cache Rust build artifacts
uses: Swatinem/rust-cache@v2
- name: Install Emscripten SDK
uses: mymindstorm/setup-emsdk@v14
with:
version: "4.0.9"
actions-cache-folder: emsdk-cache
- name: Patch Emscripten for Rust side module exports
run: |
# Rust side modules have mangled symbol names containing '$' which Emscripten
# rejects as invalid export names. These symbols are called from native code,
# not JavaScript, so the check is unnecessary for side modules.
# Upstream: https://github.com/emscripten-core/emscripten/pull/24359
EMSCRIPTEN_DIR=$(em-config EMSCRIPTEN_ROOT)
curl -sL https://raw.githubusercontent.com/pyodide/pyodide/refs/heads/main/emsdk/patches/0002-Don-t-check-exports-for-being-valid-C-C-identifiers-.patch | git -C "$EMSCRIPTEN_DIR" apply
- name: Install uv
uses: astral-sh/setup-uv@v7
- name: Build wasm wheel
env:
RUSTFLAGS: "-Zemscripten-wasm-eh"
CFLAGS: "-fPIC"
run: uvx maturin build --release --target wasm32-unknown-emscripten --out dist -i 3.13 --no-default-features --features extension-module