This commit updates the `test.yml` GitHub workflow to correctly process and locate code coverage reports before uploading them to Codecov.
The previous steps extracted coverage reports from `.tar` and `.zip` archives into subdirectories within the `coverage-reports` directory. This commit adds a step to move all extracted `.xml` files from these subdirectories into the root of the `coverage-reports` directory. Additionally, it cleans up the original `.tar` and `.zip` archives after extraction to save space. This ensures that the Codecov action can find all the necessary XML reports in the expected location.
This commit adds a new step to the `test.yml` GitHub Actions workflow to extract coverage reports from downloaded artifacts.
Previously, the workflow would download coverage report artifacts but did not extract them before the upload step. This change adds a new step named "Extract coverage reports from archives" that finds all `.tar` and `.zip` files within the `coverage-reports/` directory and extracts their contents. This ensures that the individual XML coverage files are available for the subsequent "Upload to codecov.io" step.
Problem:
Running tests and coverage report generation as separate Gradle invocations
caused a ConcurrentModificationException when Kover tried to access test
execution data:
Could not determine the dependencies of task ':app:koverGenerateArtifactStandardDebug'
> java.util.ConcurrentModificationException (no error message)
Root Cause:
- Configuration cache is enabled (improves build performance)
- Kover's coverage tasks need test execution data from the same Gradle session
- Separate invocations = separate Gradle daemon sessions
- Coverage report task cannot access test data from previous invocation
- Configuration cache + separate invocations = state corruption
Solution:
Combine test execution and coverage generation into single Gradle command:
BEFORE: ./gradlew :app:testStandardDebug
./gradlew :app:koverXmlReportStandardDebug # Fails!
AFTER: ./gradlew :app:testStandardDebug :app:koverXmlReportStandardDebug
Benefits:
- Both tasks run in same Gradle daemon session
- Coverage task has access to test execution data
- Configuration cache works correctly
- No state corruption between invocations
Applied to all test jobs:
- test-libraries: Combined 6 test + 6 coverage tasks
- test-app: Combined test + coverage
- test-authenticator: Combined test + coverage
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
Major changes:
- Split single test job into 5 parallel jobs:
1. lint-and-static-analysis: Run detekt and lint checks
2. test-libraries: Test core, data, network, ui, authenticatorbridge, cxf
3. test-app: Test app module (5,447 tests)
4. test-authenticator: Test authenticator module (281 tests)
5. aggregate-coverage: Merge coverage reports and upload to codecov
Benefits:
- 40-55% expected reduction in CI runtime
- Early failure detection (lint and library tests complete quickly)
- Better resource utilization across 5 concurrent jobs
- Maintains existing coverage reporting behavior
Technical details:
- Each test job uploads test reports and coverage data as artifacts
- Coverage aggregation job downloads all coverage artifacts
- Uses Fastlane's koverXmlReportMergedCoverage for merging
- Preserves all existing codecov.io integration
- Add org.gradle.configuration-cache=true
- Set problems to warn level to identify compatibility issues
- Expected 5-15% improvement in Gradle configuration phase
- Part of test workflow optimization (Tier 1)