name: Coverage
on:
workflow_dispatch:
inputs:
run_coverage:
description: 'Run coverage report'
required: false
type: boolean
default: true
permissions:
contents: read
actions: read
env:
CARGO_TERM_COLOR: always
RUST_BACKTRACE: '1'
CARGO_INCREMENTAL: '1'
jobs:
coverage:
name: Coverage Report
runs-on: [self-hosted, Linux, X64, builds]
if: github.event_name == 'workflow_dispatch' && github.event.inputs.run_coverage == true
steps:
- uses: actions/checkout@v4
- name: Strip [patch.crates-io] for crates.io-only CI
uses: BTCDecoded/rust-ci/strip-patch-crates-io@main
- name: Cleanup any leftover dependency directories
run: |
# Remove any leftover dependency directories from previous jobs
if [ -d "../blvm-protocol" ]; then rm -rf ../blvm-protocol; fi
if [ -d "../blvm-consensus" ]; then rm -rf ../blvm-consensus; fi
# Also remove any .cargo/config.toml that might have been left behind
if [ -f ".cargo/config.toml" ]; then rm -f .cargo/config.toml; fi
- name: Cache
run: |
CACHE_ROOT="/tmp/runner-cache"
# Generate cache key from Cargo.toml (library crate does not commit Cargo.lock)
DEPS_KEY=$(sha256sum Cargo.toml | cut -d' ' -f1)
TOOLCHAIN=$(grep -E '^channel|rust-version' rust-toolchain.toml Cargo.toml 2>/dev/null | head -1 | sha256sum | cut -d' ' -f1 || echo "1.88.0")
CACHE_KEY="${DEPS_KEY}-${TOOLCHAIN}"
CARGO_CACHE_DIR="$CACHE_ROOT/cargo/$CACHE_KEY"
TARGET_CACHE_DIR="$CACHE_ROOT/target/$CACHE_KEY"
echo "CARGO_CACHE_DIR=$CARGO_CACHE_DIR" >> $GITHUB_ENV
echo "TARGET_CACHE_DIR=$TARGET_CACHE_DIR" >> $GITHUB_ENV
- name: Restore Cargo cache
uses: BTCDecoded/rust-ci/runner-cargo-cache@main
with:
operation: restore
- name: Install Rust
uses: BTCDecoded/rust-ci/install-rust-toolchain@main
- name: Run tests with coverage
id: coverage
run: |
# Ensure cargo bin is in PATH
export PATH="$HOME/.cargo/bin:$PATH"
# Verify cargo is available
if ! command -v cargo &> /dev/null; then
echo "ERROR: cargo not found in PATH"
exit 1
fi
# Install tarpaulin with error checking
if ! cargo install cargo-tarpaulin --version 0.27.0; then
echo "ERROR: Failed to install cargo-tarpaulin"
exit 1
fi
# Run tests with coverage
# --jobs 2 limits parallelism to prevent OOM when compiling test executables
cargo tarpaulin --lib --bins --tests --all-features --out xml --output-dir coverage --skip-clean --timeout 120 --jobs 2
# Extract coverage percentage from XML
if [ -f "coverage/cobertura.xml" ]; then
COVERAGE_PCT=$(grep -oP 'line-rate="\K[0-9.]+' coverage/cobertura.xml | head -1 | awk '{printf "%.2f", $1 * 100}')
echo "coverage_percent=$COVERAGE_PCT" >> $GITHUB_OUTPUT
echo "📊 Coverage: ${COVERAGE_PCT}%"
# Warn if coverage is below 50%
if (( $(echo "$COVERAGE_PCT < 50" | bc -l) )); then
echo "⚠️ Coverage is below 50% - consider adding more tests"
fi
else
echo "coverage_percent=0.00" >> $GITHUB_OUTPUT
echo "⚠️ Coverage file not found"
fi
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v3
with:
file: coverage/cobertura.xml
flags: unittests
name: codecov-blvm-consensus
fail_ci_if_error: false
- name: Save Cargo cache
if: always()
uses: BTCDecoded/rust-ci/runner-cargo-cache@main
with:
operation: save
- name: Coverage Summary
if: always()
run: |
echo "## Coverage Report" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**Coverage**: ${{ steps.coverage.outputs.coverage_percent }}%" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "Coverage report uploaded to Codecov." >> $GITHUB_STEP_SUMMARY