name: Rust
on:
push:
branches: [main]
tags:
- v*
pull_request:
branches: [main]
paths:
- src/**
- Cargo.toml
- Cargo.lock
- .github/workflows/rust.yml
- .github/workflows/pre-commit.yml
env:
CARGO_TERM_COLOR: always
permissions:
contents: read
jobs:
build:
name: Build & test on ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macos-14]
steps:
- uses: actions/checkout@v6
- name: Cache Homebrew downloads
if: runner.os == 'macOS'
uses: actions/cache@v5
with:
path: ~/Library/Caches/Homebrew
key: ${{ runner.os }}-brew-${{ hashFiles('**/Cargo.lock', '.github/workflows/rust.yml') }}
restore-keys: |
${{ runner.os }}-brew-
- name: Install dependencies (macOS)
if: runner.os == 'macOS'
env:
HOMEBREW_NO_AUTO_UPDATE: '1' run: |
brew install gdal proj hdf5 netcdf zlib
- name: Configure native deps (macOS)
if: runner.os == 'macOS'
run: |
ZLIB_PREFIX="$(brew --prefix zlib)"
HDF5_PREFIX="$(brew --prefix hdf5)"
NETCDF_PREFIX="$(brew --prefix netcdf)"
BREW_PREFIX="$(brew --prefix)"
{
echo "LIBZ_SYS_STATIC=0"
echo "ZLIB_DIR=$ZLIB_PREFIX"
echo "HDF5_DIR=$HDF5_PREFIX"
echo "NETCDF_DIR=$NETCDF_PREFIX"
echo "ZLIB_ROOT=$ZLIB_PREFIX"
echo "HDF5_ROOT=$HDF5_PREFIX"
echo "NETCDF_ROOT=$NETCDF_PREFIX"
echo "PKG_CONFIG_PATH=$ZLIB_PREFIX/lib/pkgconfig:$HDF5_PREFIX/lib/pkgconfig:$NETCDF_PREFIX/lib/pkgconfig:$BREW_PREFIX/lib/pkgconfig"
echo "CPPFLAGS=-I$ZLIB_PREFIX/include -I$HDF5_PREFIX/include -I$NETCDF_PREFIX/include ${CPPFLAGS:-}"
echo "LDFLAGS=-L$ZLIB_PREFIX/lib -L$HDF5_PREFIX/lib -L$NETCDF_PREFIX/lib ${LDFLAGS:-}"
} >> "$GITHUB_ENV"
- name: Debug native deps (macOS)
if: runner.os == 'macOS'
run: |
echo "ZLIB_DIR=$ZLIB_DIR"
echo "HDF5_DIR=$HDF5_DIR"
echo "NETCDF_DIR=$NETCDF_DIR"
echo "PKG_CONFIG_PATH=$PKG_CONFIG_PATH"
echo "CPPFLAGS=$CPPFLAGS"
echo "LDFLAGS=$LDFLAGS"
pkg-config --modversion zlib
pkg-config --cflags zlib
pkg-config --libs zlib
pkg-config --modversion hdf5
pkg-config --cflags hdf5
pkg-config --libs hdf5
pkg-config --modversion netcdf
pkg-config --cflags netcdf
pkg-config --libs netcdf
- name: Install dependencies (Ubuntu)
if: runner.os == 'Linux'
run: |
sudo apt update -y
sudo apt install -y gdal-bin proj-bin
- name: Install dependencies (Windows GDAL + PROJ via OSGeo4W)
if: runner.os == 'Windows'
id: osgeo4w
uses: echoix/setup-OSGeo4W@v0.3.0
with:
packages: >-
gdal
proj
- name: Verify GDAL/PROJ (Windows)
if: runner.os == 'Windows'
shell: cmd
run: |
CALL "${{ steps.osgeo4w.outputs.root }}\OSGeo4W.bat" gdalinfo --version
CALL "${{ steps.osgeo4w.outputs.root }}\OSGeo4W.bat" gdallocationinfo --help > NUL
CALL "${{ steps.osgeo4w.outputs.root }}\OSGeo4W.bat" ogr2ogr --help > NUL
CALL "${{ steps.osgeo4w.outputs.root }}\OSGeo4W.bat" proj
- name: Rust toolchain
uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
- name: Verify CMake (Windows)
if: runner.os == 'Windows'
shell: cmd
run: |
"C:\Program Files\CMake\bin\cmake.exe" --version
- name: Formatting
if: runner.os == 'Linux'
id: fmt
continue-on-error: true
run: cargo fmt --check
- name: Linting
if: runner.os == 'Linux'
id: lint
continue-on-error: true
run: cargo clippy --no-default-features -F cli -- -D warnings --no-deps
- name: Build
run: cargo build --no-default-features -F cli --verbose
- name: Test (Linux)
if: runner.os == 'Linux'
run: cargo test --no-default-features -F cli -- --nocapture
- name: Test (Windows)
if: runner.os == 'Windows'
shell: cmd
env:
CMAKE: C:\Program Files\CMake\bin\cmake.exe
run: |
CALL "${{ steps.osgeo4w.outputs.root }}\OSGeo4W.bat" "%USERPROFILE%\.cargo\bin\cargo.exe" test --no-default-features -F cli -- --nocapture
- name: Test (MacOS)
if: runner.os == 'macOS'
run: cargo test --no-default-features -F cli -- --nocapture
- name: Dry-run cargo publish
if: runner.os == 'Linux' && !startsWith(github.ref, 'refs/tags/')
run: cargo publish --dry-run
- name: Fail job if fmt failed
if: runner.os == 'Linux' && steps.fmt.outcome == 'failure'
run: |
echo "Lint (cargo clippy) failed; marking job as failed."
exit 1
- name: Fail job if lint failed
if: runner.os == 'Linux' && steps.lint.outcome == 'failure'
run: |
echo "Lint (cargo clippy) failed; marking job as failed."
exit 1
coverage:
name: Coverage (ubuntu)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Install dependencies
run: |
sudo apt update -y
sudo apt install -y gdal-bin proj-bin
- uses: dtolnay/rust-toolchain@stable
with:
components: llvm-tools-preview
- uses: Swatinem/rust-cache@v2
- uses: taiki-e/install-action@cargo-llvm-cov
- run: cargo llvm-cov --workspace --all-features --lcov --output-path lcov.info
- uses: codecov/codecov-action@v6
with:
files: lcov.info
token: ${{ secrets.CODECOV_TOKEN }}
fail_ci_if_error: true
publish:
name: Publish to crates.io
runs-on: ubuntu-latest
needs: build
if: startsWith(github.ref, 'refs/tags/v')
steps:
- uses: actions/checkout@v6
- name: Rust toolchain
uses: dtolnay/rust-toolchain@stable
- name: Publish crate
env:
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
run: cargo publish