name: CI
concurrency:
group: ${{ github.repository }}-${{ github.head_ref || github.sha }}-${{ github.workflow }}
cancel-in-progress: true
on:
push:
branches: [master]
pull_request:
branches: [master]
workflow_dispatch:
permissions:
contents: read
checks: write
pull-requests: read
env:
CARGO_TERM_COLOR: always
CARGO_INCREMENTAL: '0'
RUST_BACKTRACE: 1
RUSTFLAGS: '-C debuginfo=line-tables-only'
jobs:
changes:
name: Detect Changes
runs-on: ubuntu-latest
outputs:
code: ${{ steps.changes.outputs.code }}
steps:
- uses: actions/checkout@v6
- uses: dorny/paths-filter@v3
id: changes
with:
predicate-quantifier: every
filters: |
code:
- '**'
- '!**/*.md'
- '!docs/**'
- '!.claude/**'
- '!.gitignore'
- '!LICENSE'
- '!.github/dependabot.yml'
- '!.github/labeler.yml'
checks:
name: Checks
runs-on: ubuntu-latest
needs: changes
if: needs.changes.outputs.code == 'true'
steps:
- uses: actions/checkout@v6
- name: Install system dependencies
run: sudo apt-get update && sudo apt-get install -y pkg-config libopenblas-dev
- name: Install just
uses: taiki-e/install-action@just
- name: Install Rust stable
uses: dtolnay/rust-toolchain@stable
with:
components: clippy
- name: Install Rust nightly
uses: dtolnay/rust-toolchain@nightly
with:
components: rustfmt, clippy
- name: Run repository checks
run: just checks
docs:
name: Rustdoc
runs-on: ubuntu-latest
needs: changes
if: needs.changes.outputs.code == 'true'
steps:
- uses: actions/checkout@v6
- name: Install Rust stable
uses: dtolnay/rust-toolchain@stable
- name: Install Rust nightly
uses: dtolnay/rust-toolchain@nightly
- name: Build crate docs
run: cargo doc --no-default-features --no-deps
- name: Build docs.rs-equivalent rustdoc
run: cargo +nightly rustdoc --lib --no-default-features --config 'build.rustdocflags=["--cfg","docsrs"]'
coverage:
name: Coverage
runs-on: ubuntu-latest
needs: changes
if: needs.changes.outputs.code == 'true'
steps:
- uses: actions/checkout@v6
- name: Install Rust stable
uses: dtolnay/rust-toolchain@stable
- name: Install cargo-llvm-cov
uses: taiki-e/install-action@cargo-llvm-cov
- name: Generate code coverage
run: |
cargo llvm-cov clean --workspace
cargo llvm-cov --no-default-features --features test-utils --lib --tests --no-report
cargo llvm-cov report --summary-only --ignore-filename-regex ".*/examples/.*|.*/src/udf/docs.rs" --fail-under-lines 90
cargo llvm-cov report --lcov --ignore-filename-regex ".*/examples/.*|.*/src/udf/docs.rs" --output-path lcov.info
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v5
with:
token: ${{ secrets.CODECOV_TOKEN }}
files: lcov.info
fail_ci_if_error: true
disable_telem: true
ci-success:
name: CI Success
needs: [changes, checks, docs, coverage]
runs-on: ubuntu-latest
if: always()
steps:
- name: Check if all jobs succeeded
run: |
if [[ "${{ needs.changes.outputs.code }}" == "false" ]]; then
echo "Documentation-only change"
exit 0
fi
if [[ "${{ needs.checks.result }}" != "success" ||
"${{ needs.docs.result }}" != "success" ||
"${{ needs.coverage.result }}" != "success" ]]; then
echo "One or more jobs failed"
exit 1
fi
echo "All CI jobs passed successfully"