release #77
Workflow file for this run
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: release | |
on: | |
release: | |
types: [created] | |
workflow_dispatch: | |
env: | |
CARGO_TERM_COLOR: always | |
jobs: | |
rust-test: | |
runs-on: ${{ matrix.os }} | |
strategy: | |
fail-fast: false | |
matrix: | |
os: [ubuntu-latest, macos-latest, windows-latest] | |
steps: | |
- name: Print event name ("${{ github.event_name }}") | |
run: | | |
echo "GITHUB_EVENT_NAME: $GITHUB_EVENT_NAME" | |
- name: Checkout | |
uses: actions/checkout@v1 | |
- name: Install latest stable Rust | |
uses: dtolnay/rust-toolchain@stable | |
with: | |
components: rustfmt, clippy | |
targets: x86_64-unknown-none | |
- name: Check rust formatting | |
run: cargo fmt -- --check | |
- name: Lint with clippy | |
env: | |
RUSTFLAGS: "-D warnings" | |
run: cargo clippy --all-targets --all-features | |
# The environment variable `RUSTFLAGS` doesn't actually seem to have any effect on rustdoc, | |
# but we set it here to the same value as in all other cargo runs as changing it would | |
# cause unnecessary recompilation of some dependencies. | |
- name: Check for broken doc links | |
env: | |
RUSTFLAGS: "-D warnings" | |
run: cargo rustdoc -- -D rustdoc::broken-intra-doc-links | |
- name: Test in development mode | |
env: | |
RUSTFLAGS: "-D warnings" | |
run: cargo test | |
- name: Test in release mode | |
env: | |
RUSTFLAGS: "-D warnings" | |
run: cargo test --release | |
- name: "Install cargo-msrv" | |
uses: taiki-e/install-action@v2 | |
if: matrix.os != 'windows-latest' # work around https://github.com/foresterre/cargo-msrv/issues/1036 | |
with: | |
tool: cargo-msrv | |
- name: "Verify minimum supported rust version (MSRV)" | |
if: matrix.os != 'windows-latest' # work around https://github.com/foresterre/cargo-msrv/issues/1036 | |
run: cargo msrv verify -- cargo check --all-features | |
- name: Test `no_std` compatibility | |
shell: bash | |
working-directory: ensure_no_std | |
run: cargo build | |
miri-test: | |
name: miri | |
runs-on: ${{ matrix.os }} | |
strategy: | |
fail-fast: false | |
matrix: | |
os: [ubuntu-latest, macos-latest, windows-latest] | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v1 | |
- name: Find out latest rust nightly version that has miri | |
id: rust-version | |
shell: bash | |
run: | | |
case ${{ matrix.os }} in | |
ubuntu-latest) | |
arch="x86_64-unknown-linux-gnu" | |
;; | |
macos-latest) | |
arch="x86_64-apple-darwin" | |
;; | |
windows-latest) | |
arch="x86_64-pc-windows-msvc" | |
;; | |
esac | |
version="nightly-$(curl -s https://rust-lang.github.io/rustup-components-history/$arch/miri)" | |
echo "Found version: $version" | |
echo "rustc=$version" >> $GITHUB_OUTPUT | |
- name: Install rust ${{ steps.rust-version.outputs.rustc }} | |
uses: dtolnay/rust-toolchain@master | |
with: | |
toolchain: ${{ steps.rust-version.outputs.rustc }} | |
components: miri, rust-src | |
- name: Run tests in miri | |
env: | |
RUSTFLAGS: "-Zrandomize-layout" | |
MIRIFLAGS: "-Zmiri-symbolic-alignment-check -Zmiri-disable-isolation" | |
run: cargo +${{ steps.rust-version.outputs.rustc }} miri test --no-fail-fast | |
python-test: | |
runs-on: ${{ matrix.os }} | |
strategy: | |
fail-fast: false | |
matrix: | |
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13"] | |
os: [ubuntu-latest, macos-latest, windows-latest] | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v1 | |
- name: Set up Python ${{ matrix.python-version }} | |
uses: actions/setup-python@v5 | |
with: | |
python-version: ${{ matrix.python-version }} | |
- name: Install Python dependencies | |
run: | | |
python -m pip install --upgrade pip | |
python -m pip install poetry | |
poetry install --no-root | |
- name: Install latest stable Rust | |
uses: dtolnay/rust-toolchain@stable | |
- name: Build Python package | |
run: poetry run maturin develop --release --features pybindings | |
- name: pytest with numpy version 1.x | |
if: matrix.python-version != '3.13' | |
shell: bash | |
run: | | |
poetry run python -m pip install numpy~=1.16 | |
INSTALLED_NUMPY_VERSION=$(poetry run python -c 'import numpy; print(numpy.__version__)') | |
echo "Installed numpy version: $INSTALLED_NUMPY_VERSION" | |
if [ "x${INSTALLED_NUMPY_VERSION:0:2}y" == "x1.y" ]; then | |
echo "Numpy version matches expectation." | |
else | |
echo "ERROR: wrong numpy version." | |
exit 1 | |
fi | |
poetry run pytest tests/python | tee pytest-numpy1.out | |
exit ${PIPESTATUS[0]} | |
- name: Verify that pytest used correct python version | |
if: matrix.python-version != '3.13' | |
shell: bash | |
run: | | |
USED_PYTHON_VERSION=$(grep -A1 -iE '^=+ test session starts =+$' pytest-numpy1.out | perl -ne 'if ($_ =~ / -- Python (\d+\.\d+)\.\d+/i) { print "$1"; }') | |
echo "Expected python version: ${{ matrix.python-version }}" | |
echo "Found python version: $USED_PYTHON_VERSION" | |
if [ "x${{ matrix.python-version }}y" == "x${USED_PYTHON_VERSION}y" ]; then | |
echo "Versions match." | |
else | |
echo "ERROR: versions don't match." | |
exit 1 | |
fi | |
- name: pytest with numpy version 2.x | |
if: matrix.python-version != '3.8' && matrix.python-version != '3.9' | |
shell: bash | |
run: | | |
poetry run python -m pip install numpy~=2.1 | |
INSTALLED_NUMPY_VERSION=$(poetry run python -c 'import numpy; print(numpy.__version__)') | |
echo "Installed numpy version: $INSTALLED_NUMPY_VERSION" | |
if [ "x${INSTALLED_NUMPY_VERSION:0:2}y" == "x2.y" ]; then | |
echo "Numpy version matches expectation." | |
else | |
echo "ERROR: wrong numpy version." | |
exit 1 | |
fi | |
poetry run pytest tests/python | tee pytest-numpy2.out | |
exit ${PIPESTATUS[0]} | |
- name: Verify that pytest used correct python version | |
if: matrix.python-version != '3.8' && matrix.python-version != '3.9' | |
shell: bash | |
run: | | |
USED_PYTHON_VERSION=$(grep -A1 -iE '^=+ test session starts =+$' pytest-numpy2.out | perl -ne 'if ($_ =~ / -- Python (\d+\.\d+)\.\d+/i) { print "$1"; }') | |
echo "Expected python version: ${{ matrix.python-version }}" | |
echo "Found python version: $USED_PYTHON_VERSION" | |
if [ "x${{ matrix.python-version }}y" == "x${USED_PYTHON_VERSION}y" ]; then | |
echo "Versions match." | |
else | |
echo "ERROR: versions don't match." | |
exit 1 | |
fi | |
testall: | |
runs-on: ubuntu-latest | |
name: Meta job for all tests | |
needs: [rust-test, miri-test, python-test] | |
steps: | |
- name: Done | |
run: echo "All tests successful." | |
python-doc: | |
needs: testall | |
runs-on: ubuntu-latest | |
steps: | |
- uses: actions/checkout@v1 | |
- name: Set up Python 3.13 | |
uses: actions/setup-python@v5 | |
with: | |
python-version: "3.13" | |
- name: Install Python dependencies | |
run: | | |
python -m pip install --upgrade pip | |
python -m pip install poetry | |
poetry install --no-root | |
- name: Install latest stable Rust | |
uses: dtolnay/rust-toolchain@stable | |
- name: checkout website template | |
run: | | |
git clone https://github.com/bamler-lab/constriction.git --branch website-template --single-branch website | |
rm -rf website/.git | |
CONSTRICTION_VERSION=`poetry run python get_version.py` | |
echo "Found constriction version $CONSTRICTION_VERSION." | |
sed -i "s/<\!-- CONSTRICTION_VERSION -->/$CONSTRICTION_VERSION/g" website/index.html | |
- name: generate license file | |
run: | | |
cargo install cargo-quickinstall | |
cargo quickinstall cargo-about | |
cargo about generate --features=pybindings about.hbs > website/license.html | |
wc -l website/license.html | |
- name: generate python API reference | |
run: | | |
poetry run maturin develop --features pybindings | |
poetry run python pythondoc.py website/apidoc/python | |
mv website/apidoc/python/constriction/* website/apidoc/python/ | |
rmdir website/apidoc/python/constriction | |
- name: Save artifact with website | |
uses: actions/upload-artifact@v4 | |
with: | |
name: website | |
path: ./website | |
- name: Deploy website to gh-pages branch | |
if: github.event_name == 'release' | |
uses: peaceiris/actions-gh-pages@v3 | |
with: | |
github_token: ${{ secrets.GITHUB_TOKEN }} | |
publish_dir: ./website | |
commit_message: Deploy | |
rust-publish: | |
needs: testall | |
runs-on: ubuntu-latest | |
steps: | |
- uses: actions/checkout@v1 | |
- name: Install latest stable Rust | |
uses: dtolnay/rust-toolchain@stable | |
# We don't return an error here if `cargo publish` fails for the same reason why | |
# we use `--skip-existing` in `twine upload` below. | |
- name: Publish on crates.io | |
if: github.event_name == 'release' | |
run: | | |
cargo login ${{ secrets.CARGO }} | |
cargo publish || echo "Publishing failed." | |
python-publish: | |
needs: testall | |
runs-on: ${{ matrix.os }} | |
strategy: | |
fail-fast: false | |
matrix: | |
os: [ubuntu-latest, macos-latest, windows-latest] | |
steps: | |
- uses: actions/checkout@v1 | |
- name: Install latest stable Rust | |
uses: dtolnay/rust-toolchain@stable | |
- name: Set up Python 3.8 | |
id: setup-python-3-8 | |
uses: actions/setup-python@v5 | |
with: | |
python-version: 3.8 | |
- name: Set up Python 3.9 | |
id: setup-python-3-9 | |
uses: actions/setup-python@v5 | |
with: | |
python-version: 3.9 | |
- name: Set up Python 3.10 | |
id: setup-python-3-10 | |
uses: actions/setup-python@v5 | |
with: | |
python-version: "3.10" | |
- name: Set up Python 3.11 | |
id: setup-python-3-11 | |
uses: actions/setup-python@v5 | |
with: | |
python-version: "3.11" | |
- name: Set up Python 3.12 | |
id: setup-python-3-12 | |
uses: actions/setup-python@v5 | |
with: | |
python-version: "3.12" | |
- name: Set up Python 3.13 | |
id: setup-python-3-13 | |
uses: actions/setup-python@v5 | |
with: | |
python-version: "3.13" | |
- name: generate license file | |
shell: bash | |
run: | | |
rm LICENSE.* | |
cargo install cargo-quickinstall | |
cargo quickinstall cargo-about | |
cargo about generate --features=pybindings about.hbs > LICENSE.html | |
ls -l LICENSE* | |
wc -l LICENSE* | |
- name: Build wheels (ubuntu) | |
if: matrix.os == 'ubuntu-latest' | |
uses: messense/maturin-action@v1 | |
with: | |
command: build | |
manylinux: 2014 | |
args: --release --strip --features pybindings -i python3.8 python3.9 python3.10 python3.11 python3.12 python3.13 | |
- name: Build wheels (macos) | |
if: matrix.os == 'macos-latest' | |
uses: messense/maturin-action@v1 | |
with: | |
command: build | |
args: --release --strip --features pybindings -i python3.8 python3.9 python3.10 python3.11 python3.12 python3.13 | |
- name: Build wheels (windows) | |
if: matrix.os == 'windows-latest' | |
uses: messense/maturin-action@v1 | |
with: | |
command: build | |
args: --release --strip --features pybindings -i C:\hostedtoolcache\windows\Python\${{ steps.setup-python-3-8.outputs.python-version }}\x64\python3.exe C:\hostedtoolcache\windows\Python\${{ steps.setup-python-3-9.outputs.python-version }}\x64\python3.exe C:\hostedtoolcache\windows\Python\${{ steps.setup-python-3-10.outputs.python-version }}\x64\python3.exe C:\hostedtoolcache\windows\Python\${{ steps.setup-python-3-11.outputs.python-version }}\x64\python3.exe C:\hostedtoolcache\windows\Python\${{ steps.setup-python-3-12.outputs.python-version }}\x64\python3.exe C:\hostedtoolcache\windows\Python\${{ steps.setup-python-3-13.outputs.python-version }}\x64\python3.exe | |
- name: Cross-build wheels for Apple Silicon | |
if: matrix.os == 'macos-latest' | |
uses: messense/maturin-action@v1 | |
with: | |
target: aarch64-apple-darwin | |
command: build | |
args: --release --strip --features pybindings -i python3.8 python3.9 python3.10 python3.11 python3.12 python3.13 | |
- name: Build universal2 wheels | |
if: matrix.os == 'macos-latest' | |
uses: messense/maturin-action@v1 | |
with: | |
target: universal2-apple-darwin | |
command: build | |
args: --release --strip --features pybindings -i python3.8 python3.9 python3.10 python3.11 python3.12 python3.13 | |
- name: List wheels | |
shell: bash | |
run: ls -l ./target/wheels/ | |
- name: Save artifact with wheels for ${{ matrix.os }} | |
uses: actions/upload-artifact@v4 | |
with: | |
name: wheels-${{ matrix.os }} | |
path: ./target/wheels/ | |
- name: Test install wheels | |
shell: bash | |
run: | | |
for i in target/wheels/*.whl; do | |
echo "Running: pip install $i ..." | |
pip install "$i" || echo "WARNING: unable to install $i" | |
echo "Testing if we can import constriction and numpy ..." | |
python -c 'import constriction; import numpy; print(constriction.__file__)' || echo "WARNING: unable to import constriction or numpy ($i)" | |
echo "Running: pip uninstall -y constriction numpy" | |
pip uninstall -y constriction numpy | |
echo | |
done | |
- name: Install Python dependencies (for twine) | |
run: | | |
python -m pip install --upgrade pip | |
python -m pip install poetry | |
poetry install --no-root | |
# We use `--skip-existing` here so that we can run The release script again | |
# (possibly after fixing maturin issues) if it failed on just some files. | |
- name: Publish wheels | |
if: github.event_name == 'release' | |
shell: bash | |
env: | |
TWINE_USERNAME: __token__ | |
TWINE_PASSWORD: ${{ secrets.PYPI }} | |
run: poetry run twine upload --skip-existing target/wheels/*.whl | |
- name: Add wheels to Github release | |
if: github.event_name == 'release' | |
uses: softprops/action-gh-release@v1 | |
with: | |
files: target/wheels/*.whl | |
env: | |
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} |