pyo3/.github/workflows/ci.yml
Hood Chatham da5b9814cc
Set up CI for wasm32-emscripten target (#2436)
* ci: test on emscripten target

This adds CI to build libpython3.11 for wasm32-emscripten and
running tests against it. We need to patch instant to work
around the emscripten_get_now:
https://github.com/sebcrozet/instant/pull/47

We also have to patch emscripten to work aroung the "undefined
symbol gxx_personality_v0" error:
https://github.com/emscripten-core/emscripten/issues/17128

I set up a nox file to download and install emscripten,
download and build cpython, set appropriate environment variables
then run cargo test. The workflow just installs python, rust,
node, and nox and runs the nox session.

I xfailed all the test failures. There are problems with datetime.
iter_dict_nosegv and test_filenotfounderror should probably be
fixable. The tests that involve threads or asyncio probably can't
be fixed.

* Some cleanup

* Remove instant patch

* Add explanations for xfails
2022-06-08 05:59:18 +01:00

374 lines
13 KiB
YAML

name: CI
on:
push:
branches:
- main
pull_request:
workflow_dispatch:
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.sha }}
cancel-in-progress: true
env:
CARGO_TERM_COLOR: always
jobs:
fmt:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v3
- run: pip install nox
- uses: actions-rs/toolchain@v1
with:
toolchain: stable
profile: minimal
components: rustfmt
- name: Check python formatting (black)
run: nox -s fmt-py
- name: Check rust formatting (rustfmt)
run: nox -s fmt-rust
clippy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v3
- run: pip install nox
- uses: actions-rs/toolchain@v1
with:
toolchain: stable
profile: minimal
components: clippy
- run: nox -s clippy
check-target:
needs: [fmt]
runs-on: ubuntu-latest
strategy:
# If one platform fails, allow the rest to keep testing if `CI-no-fail-fast` label is present
fail-fast: ${{ !contains(github.event.pull_request.labels.*.name, 'CI-no-fail-fast') }}
matrix:
target: [powerpc64le-unknown-linux-gnu, s390x-unknown-linux-gnu, wasm32-wasi]
name: check-${{ matrix.target }}
steps:
- uses: actions/checkout@v3
- name: Install Rust toolchain
uses: actions-rs/toolchain@v1
with:
toolchain: stable
target: ${{ matrix.target }}
profile: minimal
default: true
- name: Run cargo checks
run: |
set -x
VERSIONS=("3.7" "3.8" "3.9" "3.10")
for VERSION in ${VERSIONS[@]}; do
echo "version=$VERSION" > config.txt
echo "suppress_build_script_link_lines=true" >> config.txt
PYO3_BUILD_CONFIG=$(pwd)/config.txt cargo check --all-targets --no-default-features
PYO3_BUILD_CONFIG=$(pwd)/config.txt cargo check --all-targets --no-default-features --features "abi3"
PYO3_BUILD_CONFIG=$(pwd)/config.txt cargo check --all-targets --features full
PYO3_BUILD_CONFIG=$(pwd)/config.txt cargo check --all-targets --features "abi3 full"
done
build:
needs: [fmt] # don't wait for clippy as fails rarely and takes longer
name: python${{ matrix.python-version }}-${{ matrix.platform.python-architecture }} ${{ matrix.platform.os }} rust-${{ matrix.rust }}
runs-on: ${{ matrix.platform.os }}
strategy:
# If one platform fails, allow the rest to keep testing if `CI-no-fail-fast` label is present
fail-fast: ${{ !contains(github.event.pull_request.labels.*.name, 'CI-no-fail-fast') }}
matrix:
rust: [stable]
python-version: [
"3.7",
"3.8",
"3.9",
"3.10",
"3.11.0-beta.1",
"pypy-3.7",
"pypy-3.8",
"pypy-3.9"
]
platform:
[
{
os: "macos-latest",
python-architecture: "x64",
rust-target: "x86_64-apple-darwin",
},
{
os: "ubuntu-latest",
python-architecture: "x64",
rust-target: "x86_64-unknown-linux-gnu",
},
{
os: "windows-latest",
python-architecture: "x64",
rust-target: "x86_64-pc-windows-msvc",
},
]
include:
# Test minimal supported Rust version
- rust: 1.48.0
python-version: "3.10"
platform:
{
os: "ubuntu-latest",
python-architecture: "x64",
rust-target: "x86_64-unknown-linux-gnu",
}
msrv: "MSRV"
# Test the `nightly` feature
- rust: nightly
python-version: "3.10"
platform:
{
os: "ubuntu-latest",
python-architecture: "x64",
rust-target: "x86_64-unknown-linux-gnu",
}
extra_features: "nightly"
# Test 32-bit Windows only with the latest Python version
- rust: stable
python-version: "3.10"
platform:
{
os: "windows-latest",
python-architecture: "x86",
rust-target: "i686-pc-windows-msvc",
}
steps:
- uses: actions/checkout@v3
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v3
with:
python-version: ${{ matrix.python-version }}
architecture: ${{ matrix.platform.python-architecture }}
- name: Install Rust toolchain
uses: actions-rs/toolchain@v1
with:
toolchain: ${{ matrix.rust }}
target: ${{ matrix.platform.rust-target }}
profile: minimal
default: true
# needed to correctly format errors, see #1865
components: rust-src
- uses: Swatinem/rust-cache@v1
with:
key: cargo-${{ matrix.platform.python-architecture }}-${{ matrix.platform.os }}-${{ matrix.msrv }}
continue-on-error: true
- if: matrix.platform.os == 'ubuntu-latest'
name: Prepare LD_LIBRARY_PATH (Ubuntu only)
run: echo LD_LIBRARY_PATH=${pythonLocation}/lib >> $GITHUB_ENV
- if: matrix.msrv == 'MSRV'
name: Prepare minimal package versions (MSRV only)
run: |
set -x
cargo update -p indexmap --precise 1.6.2
cargo update -p hashbrown:0.12.1 --precise 0.9.1
PROJECTS=("." "examples/decorator" "examples/maturin-starter" "examples/setuptools-rust-starter" "examples/word-count")
for PROJ in ${PROJECTS[@]}; do
cargo update --manifest-path "$PROJ/Cargo.toml" -p parking_lot --precise 0.11.0
done
- name: Build docs
run: cargo doc --no-deps --no-default-features --features "full ${{ matrix.extra_features }}"
- name: Build (no features)
run: cargo build --lib --tests --no-default-features
# --no-default-features when used with `cargo build/test -p` doesn't seem to work!
- name: Build pyo3-build-config (no features)
run: |
cd pyo3-build-config
cargo build --no-default-features
# Run tests (except on PyPy, because no embedding API).
- if: ${{ !startsWith(matrix.python-version, 'pypy') }}
name: Test (no features)
run: cargo test --no-default-features --lib --tests
# --no-default-features when used with `cargo build/test -p` doesn't seem to work!
- name: Test pyo3-build-config (no features)
run: |
cd pyo3-build-config
cargo test --no-default-features
- name: Build (all additive features)
run: cargo build --lib --tests --no-default-features --features "full ${{ matrix.extra_features }}"
- if: ${{ startsWith(matrix.python-version, 'pypy') }}
name: Build PyPy (abi3-py37)
run: cargo build --lib --tests --no-default-features --features "abi3-py37 full ${{ matrix.extra_features }}"
# Run tests (except on PyPy, because no embedding API).
- if: ${{ !startsWith(matrix.python-version, 'pypy') }}
name: Test
run: cargo test --no-default-features --features "full ${{ matrix.extra_features }}"
# Run tests again, but in abi3 mode
- if: ${{ !startsWith(matrix.python-version, 'pypy') }}
name: Test (abi3)
run: cargo test --no-default-features --features "abi3 full ${{ matrix.extra_features }}"
# Run tests again, for abi3-py37 (the minimal Python version)
- if: ${{ (!startsWith(matrix.python-version, 'pypy')) && (matrix.python-version != '3.7') }}
name: Test (abi3-py37)
run: cargo test --no-default-features --features "abi3-py37 full ${{ matrix.extra_features }}"
- name: Test proc-macro code
run: cargo test --manifest-path=pyo3-macros-backend/Cargo.toml
- name: Test build config
run: cargo test --manifest-path=pyo3-build-config/Cargo.toml
- name: Test python examples and tests
shell: bash
run: |
python -m pip install -U pip nox
cargo xtask test-py
env:
CARGO_TARGET_DIR: ${{ github.workspace }}/target
- name: Test cross compilation
if: ${{ matrix.platform.os == 'ubuntu-latest' && matrix.python-version == '3.9' }}
uses: messense/maturin-action@v1
env:
PYO3_CROSS_LIB_DIR: /opt/python/cp39-cp39/lib
with:
target: aarch64-unknown-linux-gnu
manylinux: auto
args: --release -i python3.9 --no-sdist -m examples/maturin-starter/Cargo.toml
- run: sudo rm -rf examples/maturin-starter/target
if: ${{ matrix.platform.os == 'ubuntu-latest' && matrix.python-version == '3.9' }}
- name: Test cross compile to same architecture
if: ${{ matrix.platform.os == 'ubuntu-latest' && matrix.python-version == '3.9' }}
uses: messense/maturin-action@v1
env:
PYO3_CROSS_LIB_DIR: /opt/python/cp39-cp39/lib
with:
target: x86_64-unknown-linux-gnu
manylinux: auto
args: --release -i python3.9 --no-sdist -m examples/maturin-starter/Cargo.toml
- name: Test cross compilation
if: ${{ matrix.platform.os == 'macos-latest' && matrix.python-version == '3.9' }}
uses: messense/maturin-action@v1
with:
target: aarch64-apple-darwin
args: --release -i python3.9 --no-sdist -m examples/maturin-starter/Cargo.toml
- name: Test cross compile to Windows
if: ${{ matrix.platform.os == 'ubuntu-latest' && matrix.python-version == '3.8' }}
env:
XWIN_ARCH: x86_64
run: |
set -ex
sudo apt-get install -y mingw-w64 llvm
rustup target add x86_64-pc-windows-gnu x86_64-pc-windows-msvc
python -m pip install cargo-xwin
# abi3
cargo build --manifest-path examples/maturin-starter/Cargo.toml --features abi3 --target x86_64-pc-windows-gnu
cargo xwin build --manifest-path examples/maturin-starter/Cargo.toml --features abi3 --target x86_64-pc-windows-msvc
# non-abi3
export PYO3_CROSS_PYTHON_VERSION=3.9
cargo build --manifest-path examples/maturin-starter/Cargo.toml --features generate-import-lib --target x86_64-pc-windows-gnu
cargo xwin build --manifest-path examples/maturin-starter/Cargo.toml --features generate-import-lib --target x86_64-pc-windows-msvc
- name: Test cross compile to Windows with maturin
if: ${{ matrix.platform.os == 'ubuntu-latest' && matrix.python-version == '3.8' }}
uses: messense/maturin-action@v1
with:
target: x86_64-pc-windows-gnu
args: -i python3.8 --no-sdist -m examples/maturin-starter/Cargo.toml --cargo-extra-args="--features abi3"
env:
CARGO_TERM_VERBOSE: true
CARGO_BUILD_TARGET: ${{ matrix.platform.rust-target }}
RUST_BACKTRACE: 1
RUSTFLAGS: "-D warnings"
RUSTDOCFLAGS: "-D warnings"
# TODO: this is a hack to workaround compile_error! warnings about auto-initialize on PyPy
# Once cargo's `resolver = "2"` is stable (~ MSRV Rust 1.52), remove this.
PYO3_CI: 1
# This is a hack to make CARGO_PRIMARY_PACKAGE always set even for the
# msrv job. MSRV is currently 1.48, but CARGO_PRIMARY_PACKAGE only came in
# 1.49.
CARGO_PRIMARY_PACKAGE: 1
coverage:
needs: [fmt]
name: coverage-${{ matrix.os }}
strategy:
matrix:
os: ["windows", "macos", "ubuntu"]
runs-on: ${{ matrix.os }}-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v3
with:
python-version: "3.10"
- uses: Swatinem/rust-cache@v1
with:
key: coverage-cargo-${{ matrix.os }}
continue-on-error: true
- uses: actions-rs/toolchain@v1
with:
toolchain: stable
override: true
profile: minimal
components: llvm-tools-preview
- name: Install cargo-llvm-cov
uses: taiki-e/install-action@cargo-llvm-cov
- run: python -m pip install -U pip nox
- run: cargo xtask coverage --output-lcov coverage.lcov
- uses: codecov/codecov-action@v2
with:
file: coverage.lcov
name: ${{ matrix.os }}
emscripten:
name: emscripten
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-python@v2
with:
python-version: 3.11.0-beta.1
- name: Install Rust toolchain
uses: actions-rs/toolchain@v1
with:
toolchain: stable
target: wasm32-unknown-emscripten
- uses: actions/setup-node@v3
with:
node-version: 14
- run: pip install nox
- uses: actions/cache@v3
id: cache
with:
path: |
.nox/emscripten
key: ${{ hashFiles('emscripten/*') }} - ${{ hashFiles('noxfile.py') }}
- uses: Swatinem/rust-cache@v1
with:
key: cargo-emscripten-wasm32
- name: Build
if: steps.cache.outputs.cache-hit != 'true'
run: nox -s build_emscripten
- name: Test
run: nox -s test_emscripten