name: CI
on:
push:
branches: [main, master]
pull_request:
permissions:
contents: read
pull-requests: write
env:
CARGO_TERM_COLOR: always
jobs:
fmt:
name: Format
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Install Rust
run: |
rustup override set stable
rustup update stable
rustup component add rustfmt
- run: cargo fmt --all --check
clippy:
name: Clippy
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Install Rust
run: |
rustup override set stable
rustup update stable
rustup component add clippy
- uses: Swatinem/rust-cache@v2
- run: cargo clippy --all-targets --all-features -- -D warnings
test:
name: Test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Install Rust
run: |
rustup override set stable
rustup update stable
- uses: Swatinem/rust-cache@v2
- name: Run tests
run: cargo test --verbose --all-features --all-targets
- name: Run doc tests
run: cargo test --verbose --all-features --doc
examples:
name: Examples
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Install Rust
run: |
rustup override set stable
rustup update stable
- uses: Swatinem/rust-cache@v2
- name: Run basic_optimization
run: cargo run --example basic_optimization
- name: Run parameter_types
run: cargo run --example parameter_types --features derive
- name: Run sampler_comparison
run: cargo run --example sampler_comparison
- name: Run pruning
run: cargo run --example pruning
- name: Run early_stopping
run: cargo run --example early_stopping
- name: Run async_parallel
run: cargo run --example async_parallel --features async
- name: Run journal_storage
run: cargo run --example journal_storage --features journal
- name: Run ask_and_tell
run: cargo run --example ask_and_tell
- name: Run multi_objective
run: cargo run --example multi_objective
docs:
name: Docs
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Install Rust
run: |
rustup override set stable
rustup update stable
- uses: Swatinem/rust-cache@v2
- run: cargo doc --all-features --no-deps
env:
RUSTDOCFLAGS: -D warnings
feature-check:
name: Feature Combinations (${{ matrix.partition }}/4)
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
partition: [1, 2, 3, 4]
steps:
- uses: actions/checkout@v6
- name: Install Rust
run: |
rustup override set stable
rustup update stable
- name: Install cargo-hack
uses: taiki-e/install-action@cargo-hack
- uses: Swatinem/rust-cache@v2
- name: Check feature powerset
run: cargo hack check --feature-powerset --no-dev-deps --partition ${{ matrix.partition }}/4
coverage:
name: Coverage
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Install Rust
run: |
rustup override set stable
rustup update stable
rustup component add llvm-tools-preview
- name: Install cargo-llvm-cov
uses: taiki-e/install-action@cargo-llvm-cov
- uses: Swatinem/rust-cache@v2
- name: Generate coverage report
run: cargo llvm-cov --all-features --lcov --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
msrv:
name: MSRV (1.89)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Install Rust 1.89
run: |
rustup override set 1.89
rustup update 1.89
- uses: Swatinem/rust-cache@v2
- name: Check compilation
run: cargo check --all-features
deny:
name: Cargo Deny
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: EmbarkStudios/cargo-deny-action@v2
machete:
name: Unused Dependencies
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Install Rust
run: |
rustup override set stable
rustup update stable
- uses: Swatinem/rust-cache@v2
- name: Machete
uses: bnjbvr/cargo-machete@7959c845782fed02ee69303126d4a12d64f1db18
semver:
name: Semver Check
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Install Rust
run: |
rustup override set stable
rustup update stable
- uses: Swatinem/rust-cache@v2
- name: Install cargo-semver-checks
uses: taiki-e/install-action@cargo-semver-checks
- name: Check semver
run: cargo semver-checks check-release
minimal-versions:
name: Minimal Versions
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Install Rust nightly
run: |
rustup toolchain install nightly
rustup override set nightly
- uses: Swatinem/rust-cache@v2
- name: Generate minimal version lockfile
run: cargo +nightly -Z minimal-versions update
- name: Install Rust stable
run: |
rustup override set stable
rustup update stable
- name: Check with minimal versions
run: cargo check --all-features --locked
cross-platform:
name: ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [windows-latest, macos-latest]
steps:
- uses: actions/checkout@v6
- name: Install Rust
run: |
rustup override set stable
rustup update stable
- uses: Swatinem/rust-cache@v2
- name: Check compilation
run: cargo check --all-features
- name: Run tests
run: cargo test --all-features
cross-targets:
name: ${{ matrix.target }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
target:
- aarch64-unknown-linux-gnu
- i686-unknown-linux-gnu
- powerpc64le-unknown-linux-gnu
- s390x-unknown-linux-gnu
steps:
- uses: actions/checkout@v6
- name: Install Rust
run: |
rustup override set stable
rustup update stable
rustup target add ${{ matrix.target }}
- uses: Swatinem/rust-cache@v2
- name: Check compilation
run: cargo check --all-features --target ${{ matrix.target }}
typos:
name: Typos
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Install Rust
run: |
rustup override set stable
rustup update stable
- uses: taiki-e/cache-cargo-install-action@v3
with:
tool: typos-cli
- name: Typos Check
run: typos src/
bench-check:
name: Benchmark Smoke Test
if: github.event_name == 'push'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Install Rust
run: |
rustup override set stable
rustup update stable
- uses: Swatinem/rust-cache@v2
- name: Run benchmarks (smoke test)
run: cargo bench --all-features --bench samplers --bench optimization
bench-compare:
name: Benchmark Comparison
if: github.event_name == 'pull_request'
runs-on: ubuntu-latest
steps:
- name: Install Rust
run: |
rustup override set stable
rustup update stable
- name: Install critcmp
run: cargo install critcmp
- uses: actions/checkout@v6
with:
ref: ${{ github.event.pull_request.base.sha }}
clean: false
- uses: Swatinem/rust-cache@v2
with:
key: bench-base
- name: Bench baseline
run: cargo bench --all-features --bench samplers --bench optimization -- --save-baseline base
- uses: actions/checkout@v6
with:
ref: ${{ github.event.pull_request.head.sha }}
clean: false
- uses: Swatinem/rust-cache@v2
with:
key: bench-head
- name: Bench PR head
run: cargo bench --all-features --bench samplers --bench optimization -- --save-baseline head
- name: Compare benchmarks
id: compare
run: |
EOF=$(dd if=/dev/urandom bs=15 count=1 status=none | base64)
echo "result<<$EOF" >> "$GITHUB_OUTPUT"
critcmp base head --color never >> "$GITHUB_OUTPUT"
echo "$EOF" >> "$GITHUB_OUTPUT"
- name: Find existing comment
uses: peter-evans/find-comment@v4
id: find-comment
with:
issue-number: ${{ github.event.pull_request.number }}
comment-author: github-actions[bot]
body-includes: "## Benchmark Comparison"
- name: Post or update PR comment
uses: peter-evans/create-or-update-comment@v5
with:
comment-id: ${{ steps.find-comment.outputs.comment-id }}
issue-number: ${{ github.event.pull_request.number }}
edit-mode: replace
body: |
## Benchmark Comparison
**Base:** `${{ github.event.pull_request.base.sha }}` | **Head:** `${{ github.event.pull_request.head.sha }}`
<details>
<summary>Click to expand full results</summary>
```
${{ steps.compare.outputs.result }}
```
</details>
> Benchmarks run on `ubuntu-latest` via [Criterion](https://github.com/bheisler/criterion.rs) + [critcmp](https://github.com/BurntSushi/critcmp).
> Results may vary due to shared CI runners. Look for consistent >5% changes.
publish:
name: Publish to crates.io
runs-on: ubuntu-latest
if: github.event_name == 'push'
needs:
- fmt
- clippy
- test
- examples
- docs
- feature-check
- coverage
- msrv
- deny
- machete
- semver
- minimal-versions
- cross-platform
- cross-targets
- typos
- bench-check
steps:
- uses: actions/checkout@v6
- name: Install Rust
run: |
rustup override set stable
rustup update stable
- uses: Swatinem/rust-cache@v2
- name: Check if version already published
id: check
run: |
CARGO_VERSION=$(cargo metadata --no-deps --format-version 1 | jq -r '.packages[] | select(.name == "optimizer") | .version')
DERIVE_VERSION=$(cargo metadata --no-deps --format-version 1 | jq -r '.packages[] | select(.name == "optimizer-derive") | .version')
echo "version=$CARGO_VERSION" >> "$GITHUB_OUTPUT"
echo "derive_version=$DERIVE_VERSION" >> "$GITHUB_OUTPUT"
HTTP_STATUS=$(curl -s -o /dev/null -w "%{http_code}" "https://crates.io/api/v1/crates/optimizer/$CARGO_VERSION")
if [ "$HTTP_STATUS" = "200" ]; then
echo "Version $CARGO_VERSION already exists on crates.io, skipping publish"
echo "skip=true" >> "$GITHUB_OUTPUT"
else
echo "Version $CARGO_VERSION not found on crates.io, will publish"
echo "skip=false" >> "$GITHUB_OUTPUT"
fi
DERIVE_HTTP_STATUS=$(curl -s -o /dev/null -w "%{http_code}" "https://crates.io/api/v1/crates/optimizer-derive/$DERIVE_VERSION")
if [ "$DERIVE_HTTP_STATUS" = "200" ]; then
echo "optimizer-derive $DERIVE_VERSION already exists on crates.io"
echo "skip_derive=true" >> "$GITHUB_OUTPUT"
else
echo "optimizer-derive $DERIVE_VERSION not found on crates.io, will publish"
echo "skip_derive=false" >> "$GITHUB_OUTPUT"
fi
- name: Publish optimizer-derive
if: steps.check.outputs.skip == 'false' && steps.check.outputs.skip_derive == 'false'
run: |
cargo publish -p optimizer-derive --allow-dirty 2>&1 | tee publish_output.txt || {
if grep -q "already uploaded" publish_output.txt; then
echo "optimizer-derive already published, skipping"
exit 0
fi
exit 1
}
env:
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
- name: Wait for crates.io index update
if: steps.check.outputs.skip == 'false' && steps.check.outputs.skip_derive == 'false'
run: sleep 30
- name: Publish optimizer
if: steps.check.outputs.skip == 'false'
run: |
cargo publish --allow-dirty 2>&1 | tee publish_output.txt || {
if grep -q "already uploaded" publish_output.txt; then
echo "Version already published, skipping"
exit 0
fi
exit 1
}
env:
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}