Skip to content

Commit 054ffcc

Browse files
doublegateclaude
andcommitted
fix(ci): Fix coverage percentage extraction in GitHub Actions workflow
The "Extract coverage percentage" step in the Code Coverage workflow was failing due to attempting to parse a non-existent JSON structure in tarpaulin's output. ## Problem - Step: "Extract coverage percentage" - Error: `jq: error (at coverage/tarpaulin-report.json:0): number (0) and number (0) cannot be divided because the divisor is zero` - Cause: Workflow attempted to parse `.files` array with `.covered` and `.coverable` fields that don't exist in tarpaulin's JSON output - Actual structure: tarpaulin JSON contains `traces` and `functions` keys, not a `.files` array ## Solution **Parse tarpaulin stdout instead of JSON:** - Capture tarpaulin's stdout output during test run - Extract coverage percentage using regex pattern matching - Format: "XX.XX% coverage, N/M lines covered" - More reliable: Uses tarpaulin's own calculated percentage **Technical Details:** - Combined `tee /dev/tty` to display output while capturing - Used `grep -oP '\d+\.\d+(?=% coverage)'` for extraction - Added validation: Exit if coverage extraction fails - Store in GitHub Actions output for downstream steps ## Changes - .github/workflows/coverage.yml: - Added `id: tarpaulin` to "Generate coverage report" step - Capture tarpaulin stdout with `2>&1 | tee /dev/tty` - Extract coverage with regex: `\d+\.\d+(?=% coverage)` - Store in step outputs: `echo "coverage=$COVERAGE" >> $GITHUB_OUTPUT` - "Extract coverage percentage" step now reads from tarpaulin outputs - Added error handling for failed extraction - CHANGELOG.md: - Documented fix in [Unreleased] section - Explained root cause and solution - Related to v0.4.6 release workflow failures ## Verification - YAML syntax validated with Python yaml.safe_load() - Regex pattern tested against actual tarpaulin output: "54.85% coverage" - Solution follows GitHub Actions best practices for step outputs ## Why This Solution? Three options considered: 1. ✅ **Parse tarpaulin stdout (chosen):** Most reliable, uses tarpaulin's own calculation, simple regex, works across all versions 2. ❌ Parse LCOV file: More complex (LF/LH counting), potential precision issues 3. ❌ Use Codecov API: Requires additional API calls, async delay issues ## Impact - ✅ Coverage reporting workflow will now pass - ✅ Automated threshold checks (50%) will function correctly - ✅ PR comments will show accurate coverage percentages - ✅ Codecov integration remains unchanged (uses LCOV file) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent e2ccef1 commit 054ffcc

File tree

2 files changed

+24
-3
lines changed

2 files changed

+24
-3
lines changed

.github/workflows/coverage.yml

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,12 +52,25 @@ jobs:
5252
key: ${{ runner.os }}-cargo-build-coverage-${{ hashFiles('**/Cargo.lock') }}
5353

5454
- name: Generate coverage report
55+
id: tarpaulin
5556
run: |
56-
cargo tarpaulin --workspace \
57+
# Capture tarpaulin output to both display and parse
58+
OUTPUT=$(cargo tarpaulin --workspace \
5759
--timeout 600 \
5860
--out Lcov --out Html --out Json \
5961
--output-dir coverage \
60-
--exclude-files "crates/prtip-cli/src/main.rs"
62+
--exclude-files "crates/prtip-cli/src/main.rs" 2>&1 | tee /dev/tty)
63+
64+
# Extract coverage percentage from output (format: "XX.XX% coverage, N/M lines covered")
65+
COVERAGE=$(echo "$OUTPUT" | grep -oP '\d+\.\d+(?=% coverage)' | tail -1)
66+
67+
if [ -z "$COVERAGE" ]; then
68+
echo "Error: Could not extract coverage percentage from tarpaulin output"
69+
exit 1
70+
fi
71+
72+
echo "coverage=$COVERAGE" >> $GITHUB_OUTPUT
73+
echo "Extracted coverage: $COVERAGE%"
6174
6275
- name: Upload coverage to Codecov
6376
uses: codecov/codecov-action@v4
@@ -78,7 +91,8 @@ jobs:
7891
- name: Extract coverage percentage
7992
id: coverage
8093
run: |
81-
COVERAGE=$(jq -r '.files | map(.covered / .coverable * 100) | add / length' coverage/tarpaulin-report.json)
94+
# Get coverage from tarpaulin step output
95+
COVERAGE=${{ steps.tarpaulin.outputs.coverage }}
8296
echo "percentage=$COVERAGE" >> $GITHUB_OUTPUT
8397
echo "Current coverage: $COVERAGE%"
8498

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
### Fixed
11+
- **CI/CD:** Fixed coverage percentage extraction in GitHub Actions workflow
12+
- Root cause: Workflow was parsing non-existent `.files` array in tarpaulin JSON output
13+
- Solution: Extract coverage directly from tarpaulin stdout using regex (`XX.XX% coverage`)
14+
- Impact: Coverage reporting now works correctly, enabling automated threshold checks
15+
- Related: v0.4.6 release workflow failures resolved
16+
1017
## [0.4.6] - 2025-11-05
1118

1219
### Added - Sprint 5.6: Code Coverage Enhancement Complete

0 commit comments

Comments
 (0)