Fix coverage aggregation in parallel test workflow

Problem:
The aggregate-coverage job was failing because koverXmlReportMergedCoverage
requires all tests to have run in the same Gradle session. When tests are
split across separate jobs, Kover has no test execution data to merge.

Root Cause:
- Kover collects binary coverage data during test execution
- koverXmlReportMergedCoverage merges this data from the current build
- In parallel jobs, the aggregation job never ran any tests
- Result: No coverage data to merge, causing exit code 1

Solution:
1. Each test job now generates its own XML coverage report immediately
   after running tests:
   - test-libraries: koverXmlReportDebug for each library module
   - test-app: koverXmlReportStandardDebug
   - test-authenticator: koverXmlReportDebug

2. Coverage artifacts now contain XML reports, not just binary data

3. Aggregation job simplified:
   - Remove Fastlane/Ruby setup (no longer needed)
   - Download all coverage-* artifacts
   - Upload entire coverage-reports/ directory to codecov
   - Codecov automatically merges multiple XML files

Benefits:
- Each module's coverage is captured independently
- No dependency on cross-job Gradle state
- Codecov handles merging (tested and reliable)
- Simpler, more maintainable workflow

Technical Details:
- Kover generates XML reports at: module/build/reports/kover/report*.xml
- Codecov action with directory parameter finds all XML files recursively
- disable_search=false allows automatic file discovery
This commit is contained in:
Patrick Honkonen 2025-10-28 22:31:25 -04:00
parent d6a5f5bbc7
commit d58de79eca
No known key found for this signature in database
GPG Key ID: 27C65CF8B03CC9FB

View File

@ -113,6 +113,12 @@ jobs:
run: |
./gradlew :core:testDebug :data:testDebug :network:testDebug :ui:testDebug :authenticatorbridge:testDebug :cxf:testDebug
- name: Generate library coverage reports
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
./gradlew :core:koverXmlReportDebug :data:koverXmlReportDebug :network:koverXmlReportDebug :ui:koverXmlReportDebug :authenticatorbridge:koverXmlReportDebug :cxf:koverXmlReportDebug
- name: Upload library test reports
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
if: always()
@ -184,6 +190,11 @@ jobs:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: ./gradlew :app:testStandardDebug
- name: Generate app coverage report
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: ./gradlew :app:koverXmlReportStandardDebug
- name: Upload app test reports
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
if: always()
@ -243,6 +254,11 @@ jobs:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: ./gradlew :authenticator:testDebug
- name: Generate authenticator coverage report
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: ./gradlew :authenticator:koverXmlReportDebug
- name: Upload authenticator test reports
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
if: always()
@ -285,42 +301,11 @@ jobs:
restore-keys: |
${{ runner.os }}-gradle-v2-
- name: Configure Ruby
uses: ruby/setup-ruby@44511735964dcb71245e7e55f72539531f7bc0eb # v1.257.0
with:
bundler-cache: true
- name: Configure JDK
uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 # v5.0.0
with:
distribution: "temurin"
java-version: ${{ env._JAVA_VERSION }}
- name: Install Fastlane
run: |
gem install bundler:2.2.27
bundle config path vendor/bundle
bundle install --jobs 4 --retry 3
- name: Download all coverage artifacts
uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8
with:
pattern: coverage-*
merge-multiple: true
path: coverage-data/
- name: Generate merged coverage report
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
bundle exec fastlane koverXmlReportMergedCoverage
- name: Upload merged coverage report
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
if: always()
with:
name: merged-coverage-report
path: build/reports/kover/reportMergedCoverage.xml
path: coverage-reports/
- name: Upload to codecov.io
id: upload-to-codecov
@ -329,9 +314,9 @@ jobs:
continue-on-error: true
with:
os: linux
files: build/reports/kover/reportMergedCoverage.xml
directory: coverage-reports/
fail_ci_if_error: true
disable_search: true
disable_search: false
- name: Comment PR if coverage upload failed
if: steps.upload-to-codecov.outcome == 'failure' && (github.event_name == 'push' || github.event_name == 'pull_request')