name: Build Mac, Linux, and Windows wheels
on:
push:
branches:
- main
- dev
tags:
- "**"
pull_request:
branches:
- "**"
permissions:
contents: read
id-token: write
jobs:
build_wheels:
name: Wheel on ${{ matrix.os }} py-${{ matrix.python }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [macos-15-intel, ubuntu-latest, windows-latest]
python: ["3.10"]
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 0
- uses: chia-network/actions/setup-python@main
name: Install Python ${{ matrix.python }}
with:
python-version: ${{ matrix.python }}
- name: Update pip
run: |
python -m pip install --upgrade pip
- name: Set up rust
uses: dtolnay/rust-toolchain@stable
- name: Install dependencies
run: |
python -m pip install maturin==1.12.2 # 1.12.3 changes how `--sdist` produces artifacts, breaking CI
- name: Build MacOs with maturin on Python ${{ matrix.python }}
if: startsWith(matrix.os, 'macos')
env:
MACOSX_DEPLOYMENT_TARGET: "15.0"
run: |
python -m venv venv
ln -s venv/bin/activate
. ./activate
maturin build -m wheel/Cargo.toml --sdist -i python --release --strip --features=openssl
- name: Build Linux in manylinux_2_28 with maturin on Python ${{ matrix.python }}
if: startsWith(matrix.os, 'ubuntu')
run: |
docker run --rm \
-v ${{ github.workspace }}:/ws --workdir=/ws \
ghcr.io/chia-network/build-images/centos-pypa-rust-x86_64 \
bash -exc '\
yum -y install perl-IPC-Cmd && \
yum -y --disablerepo=epel install openssl-devel && \
source $HOME/.cargo/env && \
rustup target add x86_64-unknown-linux-musl && \
PY_VERSION=${{ matrix.python }}
PY_VERSION=${PY_VERSION/.} && \
echo "Python version with dot removed is $PY_VERSION" && \
export PATH=/opt/python/cp$PY_VERSION-cp$PY_VERSION/bin/:$PATH && \
python -m venv /venv && \
. /venv/bin/activate && \
pip install --upgrade pip && \
pip install maturin==1.12.2 && \
CC=gcc maturin build -m wheel/Cargo.toml --release --strip --manylinux 2_28 --features=openssl --sdist \
'
python -m venv venv
ln -s venv/bin/activate
- name: Build Windows with maturin on Python ${{ matrix.python }}
if: startsWith(matrix.os, 'windows')
run: |
python -m venv venv
. .\venv\Scripts\Activate.ps1
ln -s venv\Scripts\Activate.ps1 activate
maturin build -m wheel/Cargo.toml -i python --release --strip
# this will install into the venv
# it'd be better to use the wheel, but I can't figure out how to do that
# TODO: figure this out
# this does NOT work: pip install target/wheels/clvm_rs-*.whl
maturin develop --release -m wheel/Cargo.toml
# the line above also doesn't seem to work
- name: Install clvm_rs wheel
if: ${{ !startsWith(matrix.os, 'windows') }}
run: |
. ./activate
ls target/wheels/
# this mess puts the name of the `.whl` file into `$WHEEL_PATH`
# remove the dot, use the `glob` lib to grab the file from the directory
WHEEL_PATH=$(echo ${{ matrix.python }} | python -c 'DOTLESS=input().replace(".", ""); import glob; print(" ".join(glob.glob("target/wheels/clvm_rs-*-cp%s-abi3-*.whl" % DOTLESS)))' )
echo ${WHEEL_PATH}
pip install ${WHEEL_PATH}
- name: Install other wheels
run: |
. ./activate
python -m pip install pytest
python -m pip install blspy
- name: Run tests from wheel
run: |
. ./activate
cd wheel/python
pytest --import-mode append tests
# we use `append` because otherwise the `clvm_rs` source is added
# to `sys.path` and it uses that instead of the wheel (and so
# ignoring `clvm_rs.so`, which is pretty important)
- name: Upload artifacts
uses: actions/upload-artifact@v7
with:
name: wheels-${{ matrix.os }}-py-${{ matrix.python }}
path: ./target/wheels/
upload:
name: Upload to PyPI
runs-on: ubuntu-latest
needs: build_wheels
steps:
- name: Checkout code
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Install python
uses: Chia-Network/actions/setup-python@main
with:
python-version: "3.10"
- name: Download artifacts
uses: actions/download-artifact@v6
with:
merge-multiple: true
pattern: wheels-*
path: ./target/wheels/
- name: publish (PyPi)
if: startsWith(github.event.ref, 'refs/tags')
uses: pypa/gh-action-pypi-publish@release/v1
with:
packages-dir: target/wheels/
skip-existing: true
checks:
runs-on: ubuntu-22.04
name: Checks
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 1
- name: Set up rusts
uses: dtolnay/rust-toolchain@1.92.0
- name: Clippy
run: cargo clippy --all-targets --workspace -- -D warnings
- name: fmt
run: cargo fmt --all -- --files-with-diff --check
fuzz_targets:
name: Run fuzz targets
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [macos-15-intel, ubuntu-latest]
python: ["3.10"]
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 1
- name: Set up rusts
uses: dtolnay/rust-toolchain@nightly
- name: fmt
run: |
cd fuzz
cargo fmt -- --files-with-diff --check
- name: clippy
run: |
cd fuzz
cargo clippy
- name: cargo-fuzz
run: cargo install cargo-fuzz
- name: Restore fuzz corpus
uses: actions/cache/restore@v5
with:
path: fuzz/corpus
key: fuzz-corpus-${{ matrix.os }}-${{ hashFiles('fuzz/fuzz_targets/**/*.rs') }}
restore-keys: |
fuzz-corpus-${{ matrix.os }}-
- name: Build all fuzz targets
run: cargo +nightly fuzz build
- name: Run fuzz targets
run: |
for target in $(cargo +nightly fuzz list); do
cargo +nightly fuzz run "$target" -- -max_total_time=30 || exit 1
done
- name: Save fuzz corpus
uses: actions/cache/save@v5
if: always()
with:
path: fuzz/corpus
key: fuzz-corpus-${{ matrix.os }}-${{ hashFiles('fuzz/fuzz_targets/**/*.rs') }}-${{ github.run_id }}
unit_tests:
name: Unit tests
runs-on: ${{ matrix.os }}
env:
CARGO_PROFILE_RELEASE_DEBUG_ASSERTIONS: true
CARGO_PROFILE_RELEASE_OVERFLOW_CHECKS: true
strategy:
fail-fast: false
matrix:
os: [macos-15-intel, ubuntu-latest, windows-latest]
python: ["3.10"]
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 1
- name: Set up rusts
uses: dtolnay/rust-toolchain@1.92.0
- uses: chia-network/actions/setup-python@main
name: Install Python ${{ matrix.python }}
with:
python-version: ${{ matrix.python }}
- name: build
run: cargo build --workspace --exclude clvm_rs-fuzz
- name: cargo test (default)
run: cargo test && cargo test --release -- --include-ignored
- name: cargo test (allocator-debug)
run: cargo test --features allocator-debug && cargo test --features allocator-debug --release
- name: cargo test (counters)
run: cargo test --features=counters && cargo test --features=counters --release
- name: cargo test (pre-eval)
run: cargo test --features=pre-eval && cargo test --features=pre-eval --release
- name: cargo test (pre-eval and counters)
run: cargo test --features=pre-eval,counters && cargo test --features=pre-eval,counters --release
- name: cargo test (no-fastpath)
run: cargo test --features=no-fastpath && cargo test --features=no-fastpath --release
coverage:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: dtolnay/rust-toolchain@stable
- name: Run for coverage
run: |
sudo apt-get update
sudo apt-get install lcov -y
rustup component add llvm-tools-preview
export CARGOFLAGS="-j $(nproc)"
cargo install grcov
export RUSTFLAGS="-Cinstrument-coverage"
export LLVM_PROFILE_FILE=$(pwd)/target/clvm_rs-%p-%m.profraw
export CARGO_TARGET_DIR=$(pwd)/target
export RUST_TEST_THREADS=$(nproc)
cargo test --release --workspace
python -m venv venv
source venv/bin/activate
pip install colorama maturin pytest pytest-cov
maturin develop --release -m wheel/Cargo.toml --features=openssl
(cd tests && python generate-programs.py && python run-programs.py) || true
pytest wheel/python/tests --cov=clvm_rs --cov-report lcov:py_cov.info --cov-branch
grcov . --binary-path target -s . --branch --ignore-not-existing --ignore='*/.cargo/*' --ignore='target/*' -o pre_rust_cov.info
python -c 'with open("pre_rust_cov.info") as f: lines = [l for l in f if not (l.startswith("DA:") and int(l.split(",")[1].strip()) >= 2**63)]; open("rust_cov.info", "w").writelines(lines)'
lcov --add-tracefile rust_cov.info -a py_cov.info -o lcov.info
- name: Upload to Coveralls
uses: coverallsapp/github-action@v2
if: always()
continue-on-error: true
env:
COVERALLS_REPO_TOKEN: ${{ secrets.COVERALLS_REPO_TOKEN }}
with:
fail-on-error: false
path-to-lcov: "./lcov.info"