From 527037c10c2e2b9d3f69c5558054738365cc577e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 19 Jan 2026 18:14:10 +0000 Subject: [PATCH] ci(coverage): Switch to cargo-llvm-cov for code coverage - Updated .github/workflows/code_coverage.yml to use cargo-llvm-cov instead of grcov - Removed environment variables (RUSTFLAGS, RUSTDOCFLAGS, LLVM_PROFILE_FILE) - Switched to nightly toolchain for coverage generation - Enabled coverage_nightly config attribute in lib.rs - Added coverage(off) attribute to all test modules to exclude them from coverage reports - Added lint config for coverage_nightly cfg to Cargo.toml - Also add lcov.info to .gitignore to prevent accidental commits --- .github/workflows/code_coverage.yml | 32 ++++++++++++----------------- .gitignore | 3 +++ Cargo.toml | 3 +++ src/descriptor/checksum.rs | 1 + src/descriptor/dsl.rs | 1 + src/descriptor/mod.rs | 1 + src/descriptor/policy.rs | 1 + src/descriptor/template.rs | 1 + src/keys/bip39.rs | 1 + src/keys/mod.rs | 1 + src/lib.rs | 1 + src/wallet/coin_selection.rs | 1 + src/wallet/export.rs | 1 + src/wallet/mod.rs | 1 + src/wallet/signer.rs | 1 + src/wallet/tx_builder.rs | 1 + src/wallet/utils.rs | 1 + 17 files changed, 33 insertions(+), 19 deletions(-) diff --git a/.github/workflows/code_coverage.yml b/.github/workflows/code_coverage.yml index b381d3cb..d7f72223 100644 --- a/.github/workflows/code_coverage.yml +++ b/.github/workflows/code_coverage.yml @@ -1,6 +1,6 @@ name: Code Coverage -# Generates code coverage reports using grcov and uploads results to Codecov. +# Generates code coverage reports using cargo-llvm-cov and uploads results to Codecov. # Runs on every push and pull request to track test coverage metrics. # Uploads coverage data to Codecov for tracking and produces an HTML report artifact for download. @@ -14,38 +14,32 @@ jobs: Coverage: name: Code Coverage runs-on: ubuntu-latest - env: - RUSTFLAGS: "-Cinstrument-coverage" - RUSTDOCFLAGS: "-Cinstrument-coverage" - LLVM_PROFILE_FILE: "./target/coverage/%p-%m.profraw" steps: - name: Checkout uses: actions/checkout@v6 with: persist-credentials: false - - name: Install lcov tools - run: sudo apt-get install lcov -y - # This action automatically reads and applies rust-toolchain.toml - name: Install Rust toolchain uses: actions-rust-lang/setup-rust-toolchain@v1 with: + toolchain: nightly components: llvm-tools-preview cache: true - - name: Install grcov - run: if [[ ! -e ~/.cargo/bin/grcov ]]; then cargo install grcov; fi - - name: Test - run: cargo test --all-features - - name: Make coverage directory - run: mkdir coverage - - name: Run grcov - run: grcov . --binary-path ./target/debug/ -s . -t lcov --branch --ignore-not-existing --keep-only 'src/**' --ignore 'tests/**' --ignore 'examples/**' -o ./coverage/lcov.info + - name: Install cargo-llvm-cov + run: cargo install cargo-llvm-cov + - name: Generate coverage data + run: cargo llvm-cov --all-features --branch --quiet --ignore-filename-regex "test_utils" --lcov --output-path lcov.info + env: + RUSTFLAGS: "--cfg coverage_nightly" - name: Generate HTML coverage report - run: genhtml -o coverage-report.html --ignore-errors unmapped ./coverage/lcov.info + run: cargo llvm-cov --all-features --branch --quiet --ignore-filename-regex "test_utils" --html + env: + RUSTFLAGS: "--cfg coverage_nightly" - name: Codecov upload uses: codecov/codecov-action@5a1091511ad55cbe89839c7260b706298ca349f7 with: - files: ./coverage/lcov.info + files: ./lcov.info flags: rust name: codecov-bdk-wallet token: ${{ secrets.CODECOV_TOKEN }} @@ -54,4 +48,4 @@ jobs: uses: actions/upload-artifact@v6 with: name: coverage-report - path: coverage-report.html + path: target/llvm-cov/html diff --git a/.gitignore b/.gitignore index b54989de..18252155 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,6 @@ Cargo.lock *.db *.sqlite* examples/test_data + +# Coverage reports +lcov.info diff --git a/Cargo.toml b/Cargo.toml index eed208f9..9b42de68 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,6 +16,9 @@ rust-version = "1.85.0" all-features = true rustdoc-args = ["--cfg", "docsrs"] +[lints.rust] +unexpected_cfgs = { level = "warn", check-cfg = ['cfg(coverage_nightly)'] } + [dependencies] bdk_chain = { version = "0.23.1", features = ["miniscript", "serde"], default-features = false } bitcoin = { version = "0.32.7", features = ["serde", "base64"], default-features = false } diff --git a/src/descriptor/checksum.rs b/src/descriptor/checksum.rs index ccdd58d4..24937d7d 100644 --- a/src/descriptor/checksum.rs +++ b/src/descriptor/checksum.rs @@ -34,6 +34,7 @@ pub fn calc_checksum(desc: &str) -> Result { } } +#[cfg_attr(coverage_nightly, coverage(off))] #[cfg(test)] mod test { use super::*; diff --git a/src/descriptor/dsl.rs b/src/descriptor/dsl.rs index c03e6a99..eca67ecf 100644 --- a/src/descriptor/dsl.rs +++ b/src/descriptor/dsl.rs @@ -823,6 +823,7 @@ macro_rules! fragment { }); } +#[cfg_attr(coverage_nightly, coverage(off))] #[cfg(test)] mod test { use alloc::string::ToString; diff --git a/src/descriptor/mod.rs b/src/descriptor/mod.rs index 29a7f365..60cadf7d 100644 --- a/src/descriptor/mod.rs +++ b/src/descriptor/mod.rs @@ -609,6 +609,7 @@ impl DescriptorMeta for ExtendedDescriptor { } } +#[cfg_attr(coverage_nightly, coverage(off))] #[cfg(test)] mod test { use alloc::string::ToString; diff --git a/src/descriptor/policy.rs b/src/descriptor/policy.rs index b4f4d2c6..7066b86f 100644 --- a/src/descriptor/policy.rs +++ b/src/descriptor/policy.rs @@ -1173,6 +1173,7 @@ impl ExtractPolicy for Descriptor { } } +#[cfg_attr(coverage_nightly, coverage(off))] #[cfg(test)] mod test { use super::*; diff --git a/src/descriptor/template.rs b/src/descriptor/template.rs index c922242b..320b3fae 100644 --- a/src/descriptor/template.rs +++ b/src/descriptor/template.rs @@ -632,6 +632,7 @@ expand_make_bipxx!(legacy, Legacy); expand_make_bipxx!(segwit_v0, Segwitv0); expand_make_bipxx!(segwit_v1, Tap); +#[cfg_attr(coverage_nightly, coverage(off))] #[cfg(test)] mod test { // Test existing descriptor templates to make sure they are expanded to the right descriptors. diff --git a/src/keys/bip39.rs b/src/keys/bip39.rs index 76c33b23..8cd710cf 100644 --- a/src/keys/bip39.rs +++ b/src/keys/bip39.rs @@ -149,6 +149,7 @@ impl GeneratableKey for Mnemonic { } } +#[cfg_attr(coverage_nightly, coverage(off))] #[cfg(test)] mod test { use super::WordCount; diff --git a/src/keys/mod.rs b/src/keys/mod.rs index f0def348..300d4275 100644 --- a/src/keys/mod.rs +++ b/src/keys/mod.rs @@ -1041,6 +1041,7 @@ impl fmt::Display for KeyError { #[cfg(feature = "std")] impl std::error::Error for KeyError {} +#[cfg_attr(coverage_nightly, coverage(off))] #[cfg(test)] mod test { use super::*; diff --git a/src/lib.rs b/src/lib.rs index d54eac92..ecc15b85 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -5,6 +5,7 @@ docsrs, doc(html_logo_url = "https://github.com/bitcoindevkit/bdk/raw/master/static/bdk.png") )] +#![cfg_attr(coverage_nightly, feature(coverage_attribute))] #![no_std] #![warn(missing_docs)] #![allow(clippy::uninlined_format_args)] diff --git a/src/wallet/coin_selection.rs b/src/wallet/coin_selection.rs index fa032fbd..a6618185 100644 --- a/src/wallet/coin_selection.rs +++ b/src/wallet/coin_selection.rs @@ -723,6 +723,7 @@ fn calculate_cs_result( } } +#[cfg_attr(coverage_nightly, coverage(off))] #[cfg(test)] mod test { use assert_matches::assert_matches; diff --git a/src/wallet/export.rs b/src/wallet/export.rs index 7691bc96..58137abe 100644 --- a/src/wallet/export.rs +++ b/src/wallet/export.rs @@ -708,6 +708,7 @@ impl CaravanExport { } } +#[cfg_attr(coverage_nightly, coverage(off))] #[cfg(test)] mod test { use alloc::string::ToString; diff --git a/src/wallet/mod.rs b/src/wallet/mod.rs index 484702fc..79acea5d 100644 --- a/src/wallet/mod.rs +++ b/src/wallet/mod.rs @@ -2928,6 +2928,7 @@ macro_rules! doctest_wallet { }} } +#[cfg_attr(coverage_nightly, coverage(off))] #[cfg(test)] mod test { use super::*; diff --git a/src/wallet/signer.rs b/src/wallet/signer.rs index 919ebe11..54548b3d 100644 --- a/src/wallet/signer.rs +++ b/src/wallet/signer.rs @@ -918,6 +918,7 @@ impl PartialEq for SignersContainerKey { impl Eq for SignersContainerKey {} +#[cfg_attr(coverage_nightly, coverage(off))] #[cfg(test)] mod signers_container_tests { use super::*; diff --git a/src/wallet/tx_builder.rs b/src/wallet/tx_builder.rs index 885e07a0..9ad794f8 100644 --- a/src/wallet/tx_builder.rs +++ b/src/wallet/tx_builder.rs @@ -927,6 +927,7 @@ impl ChangeSpendPolicy { } } +#[cfg_attr(coverage_nightly, coverage(off))] #[cfg(test)] mod test { const ORDERING_TEST_TX: &str = "0200000003c26f3eb7932f7acddc5ddd26602b77e7516079b03090a16e2c2f54\ diff --git a/src/wallet/utils.rs b/src/wallet/utils.rs index bfabfe84..adf239f9 100644 --- a/src/wallet/utils.rs +++ b/src/wallet/utils.rs @@ -163,6 +163,7 @@ pub struct TxDetails { pub tx: Arc, } +#[cfg_attr(coverage_nightly, coverage(off))] #[cfg(test)] mod test { // When nSequence is lower than this flag the timelock is interpreted as block-height-based,