Skip to content

Commit 1d2e8f7

Browse files
Copilotdannywillems
andcommitted
Add code coverage integration with Makefile targets and nightly CI
Co-authored-by: dannywillems <[email protected]>
1 parent 234425b commit 1d2e8f7

File tree

5 files changed

+502
-0
lines changed

5 files changed

+502
-0
lines changed

.github/workflows/coverage.yaml

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
name: Code Coverage (Nightly)
2+
3+
on:
4+
schedule:
5+
# Run at 2:00 AM UTC every day
6+
- cron: '0 2 * * *'
7+
workflow_dispatch:
8+
inputs:
9+
coverage_type:
10+
description: 'Type of coverage to run'
11+
required: false
12+
default: 'comprehensive'
13+
type: choice
14+
options:
15+
- 'basic'
16+
- 'comprehensive'
17+
18+
env:
19+
CARGO_TERM_COLOR: always
20+
RUST_BACKTRACE: full
21+
OPENMINA_PANIC_ON_BUG: true
22+
23+
concurrency:
24+
group: ${{ github.workflow }}-${{ github.ref }}
25+
cancel-in-progress: true
26+
27+
jobs:
28+
code-coverage:
29+
runs-on: ubuntu-22.04
30+
31+
steps:
32+
- name: Git checkout
33+
uses: actions/checkout@v4
34+
35+
- name: Setup build dependencies
36+
run: |
37+
sudo apt update
38+
sudo apt install -y protobuf-compiler
39+
40+
- name: Setup Rust
41+
uses: dtolnay/rust-toolchain@stable
42+
with:
43+
components: rustfmt, llvm-tools-preview
44+
toolchain: 1.84
45+
46+
- name: Setup Rust Cache
47+
uses: Swatinem/rust-cache@v2
48+
with:
49+
prefix-key: "coverage-v0"
50+
51+
- name: Install grcov
52+
run: |
53+
cargo install grcov
54+
55+
- name: Determine coverage type
56+
id: coverage-type
57+
run: |
58+
if [ "${{ github.event.inputs.coverage_type }}" = "basic" ]; then
59+
echo "target=test-coverage" >> $GITHUB_OUTPUT
60+
echo "type=basic" >> $GITHUB_OUTPUT
61+
else
62+
echo "target=test-with-coverage" >> $GITHUB_OUTPUT
63+
echo "type=comprehensive" >> $GITHUB_OUTPUT
64+
fi
65+
66+
- name: Run tests with coverage
67+
run: |
68+
make ${{ steps.coverage-type.outputs.target }}
69+
70+
- name: Generate LCOV report
71+
run: |
72+
make coverage-lcov
73+
74+
- name: Generate HTML report
75+
run: |
76+
make coverage-report
77+
78+
- name: Upload coverage to Codecov
79+
uses: codecov/codecov-action@v4
80+
with:
81+
file: target/coverage/lcov.info
82+
flags: ${{ steps.coverage-type.outputs.type }}
83+
name: openmina-coverage
84+
fail_ci_if_error: true
85+
env:
86+
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
87+
88+
- name: Upload coverage reports as artifacts
89+
uses: actions/upload-artifact@v4
90+
with:
91+
name: coverage-reports-${{ steps.coverage-type.outputs.type }}
92+
path: |
93+
target/coverage/lcov.info
94+
target/coverage/html/
95+
retention-days: 30
96+
97+
- name: Coverage Summary
98+
run: |
99+
echo "## Coverage Summary" >> $GITHUB_STEP_SUMMARY
100+
echo "Coverage report type: ${{ steps.coverage-type.outputs.type }}" >> $GITHUB_STEP_SUMMARY
101+
echo "" >> $GITHUB_STEP_SUMMARY
102+
echo "### Coverage Report Files" >> $GITHUB_STEP_SUMMARY
103+
echo "- LCOV: \`target/coverage/lcov.info\`" >> $GITHUB_STEP_SUMMARY
104+
echo "- HTML Report: \`target/coverage/html/index.html\`" >> $GITHUB_STEP_SUMMARY
105+
echo "" >> $GITHUB_STEP_SUMMARY
106+
echo "### Coverage Summary" >> $GITHUB_STEP_SUMMARY
107+
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
108+
make coverage-summary >> $GITHUB_STEP_SUMMARY || echo "Coverage summary generation failed" >> $GITHUB_STEP_SUMMARY
109+
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ pkg/
1212
cargo-build-test.json
1313
tests.tsv
1414

15+
# Coverage
16+
target/coverage/
17+
1518
# Generated API docs should not be committed
1619
website/static/api-docs/
1720

Makefile

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,108 @@ test-release: ## Run tests in release mode
217217
test-vrf: ## Run VRF tests, requires nightly Rust
218218
@cd vrf && cargo +nightly test --release -- -Z unstable-options --report-time
219219

220+
# Coverage targets
221+
222+
.PHONY: setup-coverage-tools
223+
setup-coverage-tools: ## Install tools required for code coverage
224+
@echo "Installing coverage tools..."
225+
@rustup component add llvm-tools-preview
226+
@cargo install grcov || echo "grcov already installed"
227+
@echo "Coverage tools installed successfully"
228+
229+
.PHONY: test-coverage
230+
test-coverage: ## Run tests with code coverage (basic, fast)
231+
@echo "Running tests with code coverage..."
232+
@mkdir -p target/coverage
233+
@CARGO_INCREMENTAL=0 \
234+
RUSTFLAGS="-Cinstrument-coverage" \
235+
LLVM_PROFILE_FILE="target/coverage/cargo-test-%p-%m.profraw" \
236+
cargo test --workspace \
237+
--exclude fuzzer \
238+
--exclude heartbeats-processor \
239+
--lib \
240+
--tests
241+
@echo "Coverage data collected in target/coverage/"
242+
243+
.PHONY: test-with-coverage
244+
test-with-coverage: ## Run comprehensive tests with code coverage (slower, more complete)
245+
@echo "Running comprehensive tests with code coverage..."
246+
@mkdir -p target/coverage
247+
@CARGO_INCREMENTAL=0 \
248+
RUSTFLAGS="-Cinstrument-coverage" \
249+
LLVM_PROFILE_FILE="target/coverage/cargo-test-%p-%m.profraw" \
250+
cargo test --workspace \
251+
--exclude fuzzer \
252+
--exclude heartbeats-processor \
253+
--lib \
254+
--tests \
255+
--bins
256+
@echo "Coverage data collected in target/coverage/"
257+
258+
.PHONY: coverage-report
259+
coverage-report: ## Generate HTML coverage report from collected data
260+
@echo "Generating HTML coverage report..."
261+
@mkdir -p target/coverage/html
262+
@grcov target/coverage \
263+
--binary-path target/debug/deps/ \
264+
--source-dir . \
265+
--output-types html \
266+
--branch \
267+
--ignore-not-existing \
268+
--ignore "/*" \
269+
--ignore "target/*" \
270+
--ignore "tests/*" \
271+
--ignore "**/tests.rs" \
272+
--ignore "**/test_*.rs" \
273+
--ignore "**/bench_*.rs" \
274+
--ignore "**/benches/*" \
275+
--output-path target/coverage/html
276+
@echo "HTML coverage report generated in target/coverage/html/"
277+
@echo "Open target/coverage/html/index.html in your browser to view the report"
278+
279+
.PHONY: coverage-lcov
280+
coverage-lcov: ## Generate LCOV coverage report for CI/codecov
281+
@echo "Generating LCOV coverage report..."
282+
@mkdir -p target/coverage
283+
@grcov target/coverage \
284+
--binary-path target/debug/deps/ \
285+
--source-dir . \
286+
--output-types lcov \
287+
--branch \
288+
--ignore-not-existing \
289+
--ignore "/*" \
290+
--ignore "target/*" \
291+
--ignore "tests/*" \
292+
--ignore "**/tests.rs" \
293+
--ignore "**/test_*.rs" \
294+
--ignore "**/bench_*.rs" \
295+
--ignore "**/benches/*" \
296+
--output-path target/coverage/lcov.info
297+
@echo "LCOV coverage report generated at target/coverage/lcov.info"
298+
299+
.PHONY: coverage-clean
300+
coverage-clean: ## Clean coverage data and reports
301+
@echo "Cleaning coverage data..."
302+
@rm -rf target/coverage
303+
@echo "Coverage data cleaned"
304+
305+
.PHONY: coverage-summary
306+
coverage-summary: ## Display coverage summary from collected data
307+
@echo "Generating coverage summary..."
308+
@grcov target/coverage \
309+
--binary-path target/debug/deps/ \
310+
--source-dir . \
311+
--output-types markdown \
312+
--branch \
313+
--ignore-not-existing \
314+
--ignore "/*" \
315+
--ignore "target/*" \
316+
--ignore "tests/*" \
317+
--ignore "**/tests.rs" \
318+
--ignore "**/test_*.rs" \
319+
--ignore "**/bench_*.rs" \
320+
--ignore "**/benches/*"
321+
220322
# Docker build targets
221323

222324
.PHONY: docker-build-all

codecov.yml

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
codecov:
2+
require_ci_to_pass: yes
3+
notify:
4+
after_n_builds: 1
5+
6+
coverage:
7+
precision: 2
8+
round: down
9+
range: "70...95"
10+
11+
status:
12+
project:
13+
default:
14+
target: auto
15+
threshold: 1%
16+
if_not_found: success
17+
if_ci_failed: error
18+
patch:
19+
default:
20+
target: auto
21+
threshold: 1%
22+
if_not_found: success
23+
if_ci_failed: error
24+
25+
parsers:
26+
gcov:
27+
branch_detection:
28+
conditional: yes
29+
loop: yes
30+
method: no
31+
macro: no
32+
33+
ignore:
34+
- "**/*test*.rs"
35+
- "**/tests.rs"
36+
- "**/benches/**"
37+
- "**/target/**"
38+
- "**/fuzzer/**"
39+
- "**/tools/fuzzing/**"
40+
- "**/examples/**"
41+
- "**/node/testing/**"
42+
43+
comment:
44+
layout: "reach,diff,flags,tree"
45+
behavior: default
46+
require_changes: no
47+
require_base: no
48+
require_head: yes
49+
50+
github_checks:
51+
annotations: true

0 commit comments

Comments
 (0)