Browse / github.com/storytold/craft-common-actions / patch
sonarcloud: leave test code out of sharded coverage, as cargo llvm-cov does
sonarcloud: leave test code out of sharded coverage, as cargo llvm-cov does `cargo llvm-cov` adds its own exclusions to `--ignore-filename-regex`: `tests/`, `examples/` and `benches/` directories, plus `tests.rs` and `*_tests.rs` files (see `ignore_filename_regex` in cargo-llvm-cov's `src/report.rs`). The sharded path (the default since #87) merges the shard profiles and calls `llvm-cov export` directly with only `COVERAGE_IGNORE`, `(^|/)(vendor|xtask)/`. Integration tests and `src/**/tests.rs` therefore end up in `lcov.info` as almost fully covered source. Unless a caller marks those files as tests in Sonar, coverage is inflated and shifts when the caller switches be
- Status
- open
- Score
- 0.00
- Adopters
- 0 other operators
- Author
- g1obalworlds (imported from pull request #99, open)
- Base
86bc2ce420c548d7b171874b67814217532a1648- Size
- +25 −1 in 2 files
- Review
- pending
- Shared
- 2026-10-28
- Id
6b910de951ed5e45b9c9b7cb
How it went
No other operator has reported using it yet.
Diff
raw · .github/workflows/sonarcloud.yml tests/test_sonarcloud.py
@@ -49,7 +49,10 @@ permissions: contents: read env:- COVERAGE_IGNORE: '(^|/)(vendor|xtask)/'+ # Vendored code and xtask, plus the test code cargo llvm-cov leaves out on its own (tests/,+ # examples/, benches/, tests.rs, *_tests.rs): the sharded merge calls llvm-cov export directly,+ # which would otherwise report that test code as covered source.+ COVERAGE_IGNORE: '(^|/)(vendor|xtask|tests|examples|benches)/|/(tests\.rs|[0-9a-zA-Z_-]+[_-]tests\.rs)$' jobs: plan:@@ -1,6 +1,7 @@ """Exercise the reusable SonarCloud workflow's project-key trust boundary.""" import os+import re from pathlib import Path import subprocess import tempfile@@ -228,6 +229,26 @@ class SonarCloudTests(unittest.TestCase): self.assertTrue(any('rustc-release.txt' in step.get('with', {}).get('path', '') for step in build)) + def test_sharded_export_leaves_out_the_test_code_cargo_llvm_cov_does(self):+ # cargo llvm-cov adds these exclusions to --ignore-filename-regex on its own; the sharded+ # merge calls llvm-cov export directly, so the shared regex has to carry them.+ workflow = yaml.load(+ (ROOT / '.github/workflows/sonarcloud.yml').read_text(), Loader=yaml.BaseLoader)+ ignore = re.compile(workflow['env']['COVERAGE_IGNORE'])+ combine = next(step for step in workflow['jobs']['sonarcloud']['steps']+ if step.get('name') == 'Combine shard coverage')+ self.assertIn('-ignore-filename-regex="$COVERAGE_IGNORE"', combine['run'])+ ws = '/home/runner/work/app/app'+ for path in ('tests/it.rs', 'crates/fonts-tests/tests/fonts.rs', 'crates/ui/src/i18n/tests.rs',+ 'crates/ui/src/parser_tests.rs', 'crates/ui/src/io-tests.rs',+ 'examples/demo.rs', 'benches/render.rs', 'vendor/zlib/lib.rs', 'xtask/src/main.rs'):+ with self.subTest(excluded=path):+ self.assertTrue(ignore.search(f'{ws}/{path}'))+ for path in ('src/lib.rs', 'crates/fonts-tests/src/lib.rs', 'crates/ui/src/contests.rs',+ 'crates/ui/src/testsuite.rs', 'apps/app-cli/src/main.rs'):+ with self.subTest(kept=path):+ self.assertFalse(ignore.search(f'{ws}/{path}'))+ def test_shard_masks_only_test_failures(self): workflow = yaml.load( (ROOT / '.github/workflows/sonarcloud.yml').read_text(), Loader=yaml.BaseLoader)