ci: add spellcheck and binstall binaries (#19) #129
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: CI | |
on: | |
push: | |
branches: ["main"] | |
env: | |
CARGO_TERM_COLOR: always | |
RUSTFLAGS: -Dwarnings | |
RUST_BACKTRACE: 1 | |
# Change to specific Rust release to pin | |
rust_stable: stable | |
rust_nightly: nightly-2024-12-02 | |
permissions: | |
contents: read | |
defaults: | |
run: | |
shell: bash | |
jobs: | |
define-matrix: | |
needs: | |
- tests | |
- nextest_with_coverage | |
- asan | |
runs-on: ubuntu-latest | |
steps: | |
- uses: actions/checkout@v4 | |
- name: Discover benches | |
id: discover | |
run: | | |
set -euo pipefail | |
# We'll find all sub-crates, then find *.rs files under each sub-crate's benches/ directory. | |
# We assume structure like: implementations/SUBCRATE/benches/BENCH.rs | |
# Adjust globbing if needed. | |
# Find all sub crates under implementations | |
SUBCRATES=$(find implementations -mindepth 1 -maxdepth 1 -type d -printf '%f\n' || true) | |
# Convert the list of subcrates to a JSON array | |
SUBCRATES_JSON=$(echo "$SUBCRATES" | jq -R . | jq -s . | jq -c .) | |
# Output the JSON array to GitHub Actions output | |
echo "subcrates=$SUBCRATES_JSON" >> "$GITHUB_OUTPUT" | |
SUBCRATES_FOR_BENCHES=$(echo "$SUBCRATES" || true) | |
# Build a JSON array of objects | |
# Each object: { "subcrate": "xxx", "bench": "yyy" } | |
# For each subcrate, we look under benches/ for *.rs files | |
JSON='[' | |
first=true | |
for crate in $SUBCRATES_FOR_BENCHES; do | |
BENCH_FILES=$(find "implementations/$crate/benches" -maxdepth 1 -name '*.rs' -printf '%f\n' 2>/dev/null || true) | |
for bf in $BENCH_FILES; do | |
bench_name="${bf%.rs}" # remove .rs extension | |
if [ "$first" = true ]; then | |
first=false | |
else | |
JSON="$JSON," | |
fi | |
JSON="$JSON{\"subcrate\":\"$crate\",\"bench\":\"$bench_name\"}" | |
done | |
done | |
JSON="$JSON]" | |
echo "benches=$JSON" >> "$GITHUB_OUTPUT" | |
outputs: | |
benches: ${{ steps.discover.outputs.benches }} | |
subcrates: ${{ steps.discover.outputs.subcrates }} | |
bench: | |
needs: define-matrix | |
runs-on: ubuntu-latest | |
strategy: | |
# Parse the JSON output from define-matrix job | |
matrix: | |
combo: ${{ fromJSON(needs.define-matrix.outputs.benches) }} | |
steps: | |
- uses: actions/checkout@v4 | |
# Nightly Rust is used for cargo llvm-cov --doc below. | |
- name: Install Rust ${{ env.rust_nightly }} | |
uses: dtolnay/rust-toolchain@stable | |
with: | |
toolchain: ${{ env.rust_nightly }} | |
components: llvm-tools-preview | |
- uses: Swatinem/rust-cache@v2 | |
- name: Install Dependencies | |
run: | | |
sudo apt update && sudo apt install -y gnuplot jq | |
- name: Build and Run Benchmarks | |
# Run the benchmark for the specified subcrate and bench target | |
# each sub crate adjust its settings by Cargo.toml | |
run: | | |
BENCH_METRICS_PATH=/tmp/${{ matrix.combo.subcrate }}/${{ matrix.combo.bench }}.json | |
mkdir -p "$(dirname "$BENCH_METRICS_PATH")" | |
echo "BENCH_METRICS_PATH=$BENCH_METRICS_PATH" >> $GITHUB_ENV | |
# Use GNU time on Ubuntu, max_rss in KB, cpu_usage in percent | |
/usr/bin/time -f '{"max_rss_in_kb": %M, "cpu_percentage": "%P", "wall_clock_in_seconds": %e}' -o $BENCH_METRICS_PATH cargo bench -p ${{ matrix.combo.subcrate }} --bench ${{ matrix.combo.bench }} | |
# Validate JSON using jq | |
jq empty $BENCH_METRICS_PATH || (echo "Invalid JSON format in $BENCH_METRICS_PATH"; exit 1) | |
- name: Install cargo-llvm-cov | |
uses: taiki-e/install-action@v2 | |
with: | |
tool: cargo-llvm-cov | |
- name: Generate metrics.json | |
run: | | |
envsubst < .github/templates/metrics_template.json > metrics.json | |
jq empty metrics.json || (echo "Invalid JSON format in metrics.json"; exit 1) | |
cat metrics.json | |
env: | |
SUB_CRATE: ${{ matrix.combo.subcrate }} | |
BENCH: ${{ matrix.combo.bench }} | |
BENCH_METRICS_PATH: ${{ env.BENCH_METRICS_PATH }} | |
- name: | |
Send Benchmark Data to InfluxDB, along with collecting coverage data | |
run: | | |
cargo llvm-cov run --release -p bench_util --lcov --output-path lcov_bench_util.info -- update-db --metrics-config="metrics.json" --sub-crate=${{ matrix.combo.subcrate }} --bench=${{ matrix.combo.bench }} | |
env: | |
INFLUXDB_URL: ${{ secrets.INFLUXDB_URL }} | |
INFLUXDB_TOKEN: ${{ secrets.INFLUXDB_TOKEN }} | |
INFLUXDB_ORG: ${{ secrets.INFLUXDB_ORG }} | |
INFLUXDB_BUCKET: ${{ secrets.INFLUXDB_BUCKET }} | |
- name: Upload coverage data to codecov | |
uses: codecov/codecov-action@v5 | |
env: | |
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} | |
with: | |
files: lcov_bench_util.info | |
update-dashboard-time-range: | |
needs: bench | |
runs-on: ubuntu-latest | |
steps: | |
- uses: actions/checkout@v4 | |
- name: Install Rust ${{ env.rust_nightly }} | |
uses: dtolnay/rust-toolchain@stable | |
with: | |
toolchain: ${{ env.rust_nightly }} | |
components: llvm-tools-preview | |
- uses: Swatinem/rust-cache@v2 | |
- name: Install cargo-llvm-cov | |
uses: taiki-e/install-action@v2 | |
with: | |
tool: cargo-llvm-cov | |
- name: | |
Adjust Grafana dashboard's time range, along with collecting coverage | |
data | |
run: | | |
cargo llvm-cov run --release -p bench_util --lcov --output-path lcov_bench_util.info -- update-dashboard-time-range | |
env: | |
INFLUXDB_URL: ${{ secrets.INFLUXDB_URL }} | |
INFLUXDB_TOKEN: ${{ secrets.INFLUXDB_TOKEN }} | |
INFLUXDB_ORG: ${{ secrets.INFLUXDB_ORG }} | |
INFLUXDB_BUCKET: ${{ secrets.INFLUXDB_BUCKET }} | |
GRAFANA_URL: ${{ secrets.GRAFANA_URL }} | |
GRAFANA_SERVICE_ACCOUNT_TOKEN: | |
${{ secrets.GRAFANA_SERVICE_ACCOUNT_TOKEN }} | |
GRAFANA_DASHBOARD_UID: ${{ secrets.GRAFANA_DASHBOARD_UID }} | |
- name: Upload coverage data to codecov | |
uses: codecov/codecov-action@v5 | |
env: | |
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} | |
with: | |
files: lcov_bench_util.info | |
miri: | |
name: miri | |
needs: define-matrix | |
runs-on: ubuntu-latest | |
strategy: | |
matrix: | |
subcrate: ${{ fromJSON(needs.define-matrix.outputs.subcrates) }} | |
steps: | |
- uses: actions/checkout@v4 | |
- name: Install Rust ${{ env.rust_nightly }} | |
uses: dtolnay/rust-toolchain@stable | |
with: | |
toolchain: ${{ env.rust_nightly }} | |
components: miri | |
- name: Install cargo-nextest | |
uses: taiki-e/install-action@v2 | |
with: | |
tool: cargo-nextest | |
- uses: Swatinem/rust-cache@v2 | |
- name: miri | |
run: | | |
echo ${{ matrix.subcrate }} | |
cargo miri nextest run -p ${{ matrix.subcrate }} --lib --tests --no-fail-fast | |
env: | |
MIRIFLAGS: | |
-Zmiri-disable-isolation -Zmiri-strict-provenance | |
-Zmiri-retag-fields | |
asan: | |
name: asan | |
needs: basics | |
runs-on: ubuntu-latest | |
steps: | |
- uses: actions/checkout@v4 | |
- name: Install llvm | |
# Required to resolve symbols in sanitizer output | |
run: sudo apt-get install -y llvm | |
- name: Install Rust ${{ env.rust_nightly }} | |
uses: dtolnay/rust-toolchain@stable | |
with: | |
toolchain: ${{ env.rust_nightly }} | |
- uses: Swatinem/rust-cache@v2 | |
- name: asan | |
run: | |
cargo test --workspace --all-features --target | |
x86_64-unknown-linux-gnu --tests -- --test-threads 1 --nocapture | |
env: | |
RUSTFLAGS: -Z sanitizer=address | |
# Ignore `trybuild` errors as they are irrelevant and flaky on nightly | |
TRYBUILD: overwrite | |
nextest_with_coverage: | |
name: nextest_with_coverage | |
needs: | |
- basics | |
runs-on: ubuntu-latest | |
steps: | |
- uses: actions/checkout@v4 | |
# Nightly Rust is used for cargo llvm-cov --doc below. | |
- name: Install Rust ${{ env.rust_nightly }} | |
uses: dtolnay/rust-toolchain@stable | |
with: | |
toolchain: ${{ env.rust_nightly }} | |
components: llvm-tools-preview | |
- uses: Swatinem/rust-cache@v2 | |
- name: Install cargo-nextest | |
uses: taiki-e/install-action@v2 | |
with: | |
tool: cargo-nextest | |
- name: Install cargo-llvm-cov | |
uses: taiki-e/install-action@v2 | |
with: | |
tool: cargo-llvm-cov | |
- name: Collect coverage data | |
# Generate separate reports for nextest and doctests, and combine them. | |
run: | | |
cargo llvm-cov --no-report nextest | |
cargo llvm-cov --no-report --doc | |
cargo llvm-cov report --doctests --lcov --output-path lcov.info | |
- name: Upload coverage data to codecov | |
uses: codecov/codecov-action@v5 | |
env: | |
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} | |
with: | |
files: lcov.info | |
tests: | |
name: tests | |
runs-on: ubuntu-latest | |
needs: | |
- basics | |
steps: | |
- uses: actions/checkout@v4 | |
- name: Install Rust ${{ env.rust_nightly }} | |
uses: dtolnay/rust-toolchain@stable | |
with: | |
toolchain: ${{ env.rust_nightly }} | |
- uses: Swatinem/rust-cache@v2 | |
# Test **all** crates in the workspace with all features. | |
- name: test all --all-features | |
run: | | |
cargo test --workspace --all-features | |
# Basic actions that must pass before we kick off more expensive tests. | |
basics: | |
runs-on: ubuntu-latest | |
steps: | |
- uses: actions/checkout@v4 | |
- uses: ./.github/actions/basics | |
with: | |
rust_nightly: ${{ env.rust_nightly }} |