Skip to content

Commit 2e22008

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

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
@@ -227,6 +227,108 @@ test-release: ## Run tests in release mode
227227
test-vrf: ## Run VRF tests, requires nightly Rust
228228
@cd vrf && cargo +nightly test --release -- -Z unstable-options --report-time
229229

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

232334
.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)