name: CI
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
env:
CARGO_TERM_COLOR: always
jobs:
test:
name: Test
runs-on: ubuntu-latest
strategy:
matrix:
rust:
- stable
- beta
- nightly
steps:
- uses: actions/checkout@v4
- name: Install Rust
uses: dtolnay/rust-toolchain@master
with:
toolchain: ${{ matrix.rust }}
- name: Cache dependencies
uses: actions/cache@v6
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
- name: Run tests
run: cargo test --all-features --verbose
- name: Run doctests
run: cargo test --doc --all-features --verbose
fmt:
name: Rustfmt
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
with:
components: rustfmt
- name: Check formatting
run: cargo fmt --all -- --check
clippy:
name: Clippy
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
with:
components: clippy
- name: Cache dependencies
uses: actions/cache@v6
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-cargo-clippy-${{ hashFiles('**/Cargo.lock') }}
- name: Run clippy
run: cargo clippy --all-targets --all-features --workspace -- -W clippy::pedantic -D warnings -W unused_must_use
coverage:
name: Coverage
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: taiki-e/install-action@v2
with:
tool: just,cargo-llvm-cov
- uses: dtolnay/rust-toolchain@stable
with:
components: llvm-tools-preview
- name: Cache dependencies
uses: actions/cache@v6
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-cargo-llvmcov-${{ hashFiles('**/Cargo.lock') }}
- name: Coverage (lcov + summary)
run: just coverage-lcov
- uses: actions/upload-artifact@v4
with:
name: coverage-lcov
path: lcov.info
coverage-pages:
name: Coverage (Pages)
runs-on: ubuntu-latest
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
permissions:
contents: read
pages: write
id-token: write
concurrency:
group: pages
cancel-in-progress: false
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- uses: actions/checkout@v4
- uses: taiki-e/install-action@v2
with:
tool: just,cargo-llvm-cov
- uses: dtolnay/rust-toolchain@stable
with:
components: llvm-tools-preview
- name: Cache dependencies
uses: actions/cache@v6
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-cargo-llvmcov-${{ hashFiles('**/Cargo.lock') }}
- name: Generate HTML coverage report
run: just coverage --html
- name: Write coverage badge JSON
run: |
set -euo pipefail
pct=$(cargo llvm-cov report --json --summary-only --ignore-filename-regex 'tests/' \
| jq -r '.data[0].totals.lines.percent')
if awk "BEGIN{exit !($pct>=90)}"; then color=brightgreen
elif awk "BEGIN{exit !($pct>=75)}"; then color=green
elif awk "BEGIN{exit !($pct>=60)}"; then color=yellow
elif awk "BEGIN{exit !($pct>=40)}"; then color=orange
else color=red
fi
printf '{"schemaVersion":1,"label":"coverage","message":"%.1f%%","color":"%s"}\n' \
"$pct" "$color" > target/llvm-cov/html/coverage.json
cat target/llvm-cov/html/coverage.json
- uses: actions/configure-pages@v5
- uses: actions/upload-pages-artifact@v3
with:
path: target/llvm-cov/html
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
package-size:
name: Check Package Size
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- name: Check package size
run: |
# Run dry-run and capture output
echo "Checking package size..."
DRY_RUN_OUTPUT=$(cargo publish --dry-run 2>&1)
# Extract size from output (format: "Packaged X files, Y.ZKiB (A.BKiB compressed)")
SIZE_LINE=$(echo "$DRY_RUN_OUTPUT" | grep -E "Packaged.*\([0-9.]+[KM]iB compressed\)")
if [ -z "$SIZE_LINE" ]; then
echo "Warning: Could not extract package size from output"
echo "Dry run output:"
echo "$DRY_RUN_OUTPUT"
else
# Extract compressed size (the one in parentheses)
COMPRESSED_SIZE=$(echo "$SIZE_LINE" | sed -E 's/.*\(([0-9.]+)([KM])iB compressed\).*/\1 \2/')
SIZE_NUM=$(echo "$COMPRESSED_SIZE" | cut -d' ' -f1)
SIZE_UNIT=$(echo "$COMPRESSED_SIZE" | cut -d' ' -f2)
echo "Package compressed size: ${SIZE_NUM}${SIZE_UNIT}iB"
# Convert to KB for comparison
if [ "$SIZE_UNIT" = "M" ]; then
SIZE_KB=$(echo "$SIZE_NUM * 1024" | bc | cut -d. -f1)
else
SIZE_KB=$(echo "$SIZE_NUM" | cut -d. -f1)
fi
# Check if size exceeds 50KB
if [ "$SIZE_KB" -gt 50 ]; then
echo "::warning::Package size (${SIZE_KB}KB) exceeds 50KB limit"
echo "Consider:"
echo " - Reviewing included files in Cargo.toml"
echo " - Checking for unnecessary test assets"
echo " - Using exclude patterns for large files"
# Don't fail CI, just warn
else
echo "✓ Package size check passed (${SIZE_KB}KB <= 50KB)"
fi
fi