ci: build the Python package with maturin and run its tests against h5py

ci-test.sh gains a step that lints clawhdf5-py, builds its wheel with
maturin, unpacks it under target/ (the interpreter's environment is not
touched) and runs the pytest suite, which compares reads with h5py. It
skips without maturin/pytest, and fails instead under
CLAWHDF5_REQUIRE_INTEROP=1. The CI interop venv installs maturin and
pytest, so CI runs it.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
This commit is contained in:
osobh
2026-09-26 08:21:14 -05:00
co-authored by Claude Opus 5.5
parent 2d4b211523
commit f7d88bb4fb
3 changed files with 43 additions and 3 deletions
+35 -2
View File
@@ -7,7 +7,9 @@
#
# Environment:
# CLAWHDF5_REQUIRE_INTEROP=1 Fail (instead of skip) when python3 with
# h5py/netCDF4/xarray is missing. CI sets this.
# h5py/netCDF4/xarray is missing, or without
# maturin/pytest for the Python package step.
# CI sets this.
# Unset locally, the interop steps are skipped
# if python3+h5py is not importable.
# CLAWHDF5_FUZZ_SECONDS=N Run each cargo-fuzz target for N seconds
@@ -55,7 +57,8 @@ run_step "cargo fmt --check" cargo fmt --check
# 2. Clippy over every target (lib, bins, tests, benches, examples). Without
# --all-targets, test and bench code is never linted. clawhdf5-py is
# excluded because it needs PyO3/Python headers.
# excluded here: PyO3 needs a Python interpreter to build, so it is
# linted in the Python package step (5b) instead.
run_step "cargo clippy --all-targets" cargo clippy \
--workspace \
--exclude clawhdf5-py \
@@ -216,6 +219,36 @@ else
STEPS+=("SKIP: h5py interop (format, ignored tests)")
fi
# 5b. The Python package (crates/clawhdf5-py): lint it, build the wheel with
# maturin and run its pytest suite, which compares every read with h5py.
# The wheel is unpacked under target/ and put on PYTHONPATH, so the
# interpreter's environment is left as it was. Needs maturin and pytest
# in $PYTHON (CI installs both); skipped without them, and a failure
# instead when CLAWHDF5_REQUIRE_INTEROP=1.
python_package() {
local root="$SCRIPT_DIR/.." out
out="${CARGO_TARGET_DIR:-$root/target}/py-package"
rm -rf "$out" && mkdir -p "$out/wheel" "$out/site" || return 1
cargo clippy -p clawhdf5-py --all-targets -- -D warnings || return 1
"$PYTHON" -m maturin build \
-m "$root/crates/clawhdf5-py/Cargo.toml" \
-i "$PYTHON" \
--out "$out/wheel" || return 1
"$PYTHON" -m pip install --quiet --no-deps --target "$out/site" "$out"/wheel/*.whl || return 1
PYTHONPATH="$out/site" "$PYTHON" -m pytest -q -p no:cacheprovider \
"$root/crates/clawhdf5-py/tests"
}
if "$PYTHON" -m maturin --version >/dev/null 2>&1 && "$PYTHON" -c "import pytest" >/dev/null 2>&1; then
run_step "Python package (maturin build + pytest vs h5py)" python_package
elif [ "${CLAWHDF5_REQUIRE_INTEROP:-0}" = "1" ]; then
run_step "Python package (maturin build + pytest vs h5py)" \
bash -c "echo \"maturin and pytest are required in $PYTHON (CLAWHDF5_REQUIRE_INTEROP=1)\"; exit 1"
else
echo ""
echo "==> [Python package] SKIPPED: needs maturin and pytest in $PYTHON"
STEPS+=("SKIP: Python package (maturin build + pytest)")
fi
# 6. Benches must keep compiling (they are not run).
run_step "cargo bench --no-run" cargo bench \
--workspace \