Skip to content

Commit 0121ab2

Browse files
leogdionclaude
andcommitted
fix: implement proper 2-step Android coverage workflow
Research showed we were missing the llvm-profdata merge step that Android developers use. The correct workflow per Android documentation: 1. llvm-profdata merge: Convert profraw → profdata 2. llvm-cov export: Convert profdata → lcov We were trying to use llvm-cov export directly on profraw files, which causes "bad magic" errors because llvm-cov expects profdata. The merge step is required even for single profraw files - it's not just for combining multiple profiles, it's a necessary format conversion. Using Swift toolchain's llvm-profdata and llvm-cov ensures version compatibility since they match the clang that generated the profraw. References: - Android native coverage docs: https://android.googlesource.com/platform/build/soong/+/master/docs/native_code_coverage.md - LLVM version matching: https://discourse.llvm.org/t/error-invalid-file-format-bad-magic-with-fprofile-instr-use/32852 - Profile format spec: https://leodido.dev/demystifying-profraw/ 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <[email protected]>
1 parent 5fd3751 commit 0121ab2

File tree

2 files changed

+34
-6
lines changed

2 files changed

+34
-6
lines changed

.github/actions/swift-android-action/action.yml

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -599,8 +599,30 @@ runs:
599599
echo " fi" >> ${SCRIPT_FILE}
600600
echo "done" >> ${SCRIPT_FILE}
601601
602-
echo "echo '==> NOTE: profraw files from Swift Android cannot be processed by llvm-cov'" >> ${SCRIPT_FILE}
603-
echo "echo '==> Files saved to artifacts for investigation'" >> ${SCRIPT_FILE}
602+
# Convert profraw to LCOV using Swift toolchain (2-step process per Android docs)
603+
echo "echo '==> Converting profraw to LCOV format...'" >> ${SCRIPT_FILE}
604+
echo "if [ -f '${COVERAGE_DIR}/default.profraw' ]; then" >> ${SCRIPT_FILE}
605+
echo " # Find the test binary" >> ${SCRIPT_FILE}
606+
echo " TEST_BINARY=\$(find \${SWIFT_SDK_TARGET}/debug -name '*.xctest' | head -n 1)" >> ${SCRIPT_FILE}
607+
echo " if [ -n \"\$TEST_BINARY\" ]; then" >> ${SCRIPT_FILE}
608+
echo " # Step 1: Merge profraw -> profdata (required even for single file)" >> ${SCRIPT_FILE}
609+
echo " SWIFT_PROFDATA=\"\${SWIFT_INSTALLATION}/bin/llvm-profdata\"" >> ${SCRIPT_FILE}
610+
echo " SWIFT_LLVM_COV=\"\${SWIFT_INSTALLATION}/bin/llvm-cov\"" >> ${SCRIPT_FILE}
611+
echo " if [ -f \"\$SWIFT_PROFDATA\" ] && [ -f \"\$SWIFT_LLVM_COV\" ]; then" >> ${SCRIPT_FILE}
612+
echo " echo \"Step 1: Merging profraw to profdata...\"" >> ${SCRIPT_FILE}
613+
echo " \"\$SWIFT_PROFDATA\" merge -sparse '${COVERAGE_DIR}/default.profraw' -o '${COVERAGE_DIR}/default.profdata' && {" >> ${SCRIPT_FILE}
614+
echo " echo \"Step 2: Exporting profdata to LCOV...\"" >> ${SCRIPT_FILE}
615+
echo " \"\$SWIFT_LLVM_COV\" export -format=lcov -instr-profile='${COVERAGE_DIR}/default.profdata' \"\$TEST_BINARY\" > '${COVERAGE_DIR}/coverage.lcov' && {" >> ${SCRIPT_FILE}
616+
echo " echo \"Successfully generated coverage.lcov\"" >> ${SCRIPT_FILE}
617+
echo " } || echo \"Warning: llvm-cov export failed\"" >> ${SCRIPT_FILE}
618+
echo " } || echo \"Warning: llvm-profdata merge failed\"" >> ${SCRIPT_FILE}
619+
echo " else" >> ${SCRIPT_FILE}
620+
echo " echo \"Warning: Swift LLVM tools not found\"" >> ${SCRIPT_FILE}
621+
echo " fi" >> ${SCRIPT_FILE}
622+
echo " else" >> ${SCRIPT_FILE}
623+
echo " echo \"Warning: Test binary not found\"" >> ${SCRIPT_FILE}
624+
echo " fi" >> ${SCRIPT_FILE}
625+
echo "fi" >> ${SCRIPT_FILE}
604626
605627
# List retrieved files for verification
606628
echo "echo '==> Coverage files retrieved:'" >> ${SCRIPT_FILE}

.github/workflows/MistKit.yml

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -173,10 +173,16 @@ jobs:
173173
collect-coverage: true
174174
coverage-output-dir: .build/coverage-android
175175

176-
# Note: Android coverage cannot be uploaded to Codecov due to Swift Android tooling limitations
177-
# The profraw files cannot be processed by any available llvm-cov (host, NDK, or Swift toolchain)
178-
# All attempts result in "bad magic" or "version mismatch" errors
179-
# Keeping profraw files as artifacts for future investigation
176+
- name: Upload coverage to Codecov
177+
if: success() && hashFiles('coverage-android/coverage.lcov') != ''
178+
uses: codecov/codecov-action@v4
179+
with:
180+
fail_ci_if_error: false
181+
flags: android-api34-swift-nightly
182+
verbose: true
183+
token: ${{ secrets.CODECOV_TOKEN }}
184+
files: coverage-android/coverage.lcov
185+
# LCOV generated via llvm-profdata merge + llvm-cov export (Android native workflow)
180186

181187
- name: Upload Android coverage files as artifact
182188
if: always()

0 commit comments

Comments
 (0)