Files
rust-optimizer/.github/workflows/ci.yml
T
Manuel Raimann e359392a00 feat: add HTML visualization reports with Plotly.js charts
Add a `visualization` feature flag that generates self-contained HTML
reports with interactive Plotly.js charts for offline visualization of
optimization results. Charts include optimization history, slice plots,
parallel coordinates, parameter importance, trial timeline, and
intermediate values (learning curves).
2026-02-11 20:12:35 +01:00

408 lines
12 KiB
YAML

name: CI
on:
push:
branches: [main, master]
pull_request:
branches: [main, master]
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
strategy:
matrix:
features:
- ""
- "async"
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: |
if [ -z "${{ matrix.features }}" ]; then
cargo test --verbose
else
cargo test --verbose --features "${{ matrix.features }}"
fi
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 sync example (ml_hyperparameter_tuning)
run: cargo run --example ml_hyperparameter_tuning
- name: Run sync example (benchmark_convergence)
run: cargo run --example benchmark_convergence
- name: Run derive example (parameter_api)
run: cargo run --example parameter_api --features derive
- name: Run async example (async_api_optimization)
run: cargo run --example async_api_optimization --features async
- name: Run visualization example (visualization_demo)
run: cargo run --example visualization_demo --features visualization
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
runs-on: ubuntu-latest
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
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.88)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Install Rust 1.88
run: |
rustup override set 1.88
rustup update 1.88
- 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
# --- Run benchmarks on the BASE (target) branch ---
- 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
# --- Run benchmarks on the HEAD (PR) branch ---
- 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
# --- Compare and post comment ---
- 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
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[0].version')
echo "version=$CARGO_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
- name: Publish
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 }}