name: rust-tests
permissions:
contents: read
on:
push:
branches: [main]
pull_request:
workflow_dispatch:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
test_matrix:
name: test (OS=${{ matrix.os }}, Features=${{ matrix.name }})
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
include:
- name: "All Features"
flags: "--all-features"
steps:
- name: Checkout repository
uses: actions/checkout@v6
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
- name: Capture rustc commit hash
id: rustc
shell: bash
run: |
set -euo pipefail
rustc -Vv
echo "hash=$(rustc -Vv | sed -n 's/^commit-hash: //p')" >> "$GITHUB_OUTPUT"
- name: Calculate lockfile hash
id: lockfile
shell: bash
run: |
if command -v sha256sum >/dev/null 2>&1; then
HASH=$(sha256sum Cargo.lock | awk '{print $1}')
elif command -v shasum >/dev/null 2>&1; then
HASH=$(shasum -a 256 Cargo.lock | awk '{print $1}')
else
echo "No hashing utility found"
exit 1
fi
echo "hash=$HASH" >> "$GITHUB_OUTPUT"
- name: Cache Cargo dependencies
uses: actions/cache@v4
with:
path: |
~/.cargo/bin/
~/.cargo/registry/index/
~/.cargo/registry/cache/
~/.cargo/git/db/
target/
key: ${{ runner.os }}-cargo-${{ steps.rustc.outputs.hash }}-${{ steps.lockfile.outputs.hash }}-${{ matrix.flags }}
restore-keys: |
${{ runner.os }}-cargo-${{ steps.rustc.outputs.hash }}-${{ steps.lockfile.outputs.hash }}-
- name: Test
run: cargo test --workspace --all-features --lib --bins --tests --examples -- --include-ignored
- name: Ensure .cache was not created by tests
shell: bash
run: |
if [ -e ".cache" ]; then
echo "ERROR: .cache directory was created during tests" >&2
find .cache -mindepth 1 >&2
exit 1
fi
test:
name: test
runs-on: ubuntu-latest
needs: test_matrix
if: ${{ always() }}
steps:
- name: Evaluate matrix results
run: |
result="${{ needs.test_matrix.result }}"
echo "Matrix job concluded with: ${result}"
if [ "${result}" != "success" ]; then
exit 1
fi
echo "All platform combinations succeeded."
coverage:
name: coverage (cargo-llvm-cov)
runs-on: ubuntu-latest
needs: test_matrix
outputs:
line_coverage: ${{ steps.cov-summary.outputs.line_percent }}
steps:
- name: Checkout repository
uses: actions/checkout@v6
- name: Install Rust with llvm-tools
uses: dtolnay/rust-toolchain@stable
with:
components: llvm-tools-preview
- name: Install cargo-llvm-cov
uses: taiki-e/install-action@v2
with:
tool: cargo-llvm-cov
- name: Capture rustc commit hash
id: rustc-cov
shell: bash
run: |
set -euo pipefail
rustc -Vv
echo "hash=$(rustc -Vv | sed -n 's/^commit-hash: //p')" >> "$GITHUB_OUTPUT"
- name: Calculate lockfile hash
id: lockfile-cov
shell: bash
run: |
if command -v sha256sum >/dev/null 2>&1; then
HASH=$(sha256sum Cargo.lock | awk '{print $1}')
elif command -v shasum >/dev/null 2>&1; then
HASH=$(shasum -a 256 Cargo.lock | awk '{print $1}')
else
echo "No hashing utility found"
exit 1
fi
echo "hash=$HASH" >> "$GITHUB_OUTPUT"
- name: Cache Cargo dependencies
uses: actions/cache@v4
with:
path: |
~/.cargo/bin/
~/.cargo/registry/index/
~/.cargo/registry/cache/
~/.cargo/git/db/
target/
key: cov-${{ runner.os }}-${{ steps.rustc-cov.outputs.hash }}-${{ steps.lockfile-cov.outputs.hash }}
restore-keys: |
cov-${{ runner.os }}-${{ steps.rustc-cov.outputs.hash }}-
- name: Generate coverage data
shell: bash
run: |
set -euo pipefail
cargo llvm-cov clean --workspace
cargo llvm-cov --workspace --all-features --lcov --output-path lcov.info
cargo llvm-cov --workspace --all-features --summary-only > coverage-summary.txt
cat coverage-summary.txt
- name: Parse coverage summary
id: cov-summary
shell: bash
run: |
set -euo pipefail
percent=$(awk '/^TOTAL/ {print $10}' coverage-summary.txt | tr -d '%' | head -n1)
if [ -z "$percent" ]; then
percent="0"
fi
echo "line_percent=${percent}" >> "$GITHUB_OUTPUT"
- name: Upload coverage summary
if: always()
shell: bash
run: |
if [ -f coverage-summary.txt ]; then
{
echo "### Coverage summary"
echo
cat coverage-summary.txt
} >> "$GITHUB_STEP_SUMMARY"
fi
- name: Upload to Coveralls
uses: coverallsapp/github-action@v2
continue-on-error: true
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
path-to-lcov: lcov.info