feat(ci): no-regression JVM coverage gate scoped to the testable surface
Scope :app:jacocoTestReport's denominator to the JVM-testable surface and add a :app:jacocoTestCoverageVerification no-regression gate that shares the same classDirectories/executionData/sourceDirectories, wired into both the `check` lifecycle task and CI's unit-test job (part of the `CI passed` gate). Excluded from the denominator (structurally unreachable from a JVM unit test): Compose screen/component render code, Android framework entry points (*Activity/*Service/Application/*BackupAgent), Hilt DI (**/di/**), and the src/debug cold-open probe. Kept in scope: ViewModels, repositories, mappers, DAOs, utils, richtext, mail, reporting logic, and the six WorkManager Workers. Corrects PR #292, which excluded **/*Worker*: SyncWorker, BackfillWorker, PruneWorker, SendWorker, ReportPurgeWorker and ReportUploadWorker are all directly unit-tested, so they stay counted in both numerator and denominator (only their Hilt wiring, WorkManagerModule, is excluded, via **/di/**). Baseline: 80.21% line (4838/6032). Floor: 0.79 (~1.2% headroom) so ordinary noise doesn't red-flag it while a real drop fails. Manual ratchet for now: bump the floor up in the same PR when coverage rises materially. Closes #251 Closes #292 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -346,9 +346,10 @@ jobs:
|
||||
path: app/build/reports/tests/testDebugUnitTest/
|
||||
if-no-files-found: warn
|
||||
|
||||
# JaCoCo XML + HTML coverage for the JVM unit tests (issue #192). Reporting only — no
|
||||
# threshold gate yet, so a coverage regression does not fail CI (a jacocoTestCoverageVerification
|
||||
# gate is a natural follow-up once there's a baseline to enforce).
|
||||
# JaCoCo XML + HTML coverage for the JVM unit tests (issue #192), scoped to the JVM-testable
|
||||
# surface (issues #290/#292). The report is generated and uploaded first, then a no-regression
|
||||
# gate (issue #251) fails the job if overall LINE coverage drops below the floor pinned in
|
||||
# app/build.gradle.kts. Kept in this unit-test job so it is part of the `CI passed` gate.
|
||||
- name: Generate JaCoCo coverage report
|
||||
if: ${{ !cancelled() }}
|
||||
run: ./gradlew :app:jacocoTestReport --stacktrace
|
||||
@@ -361,6 +362,13 @@ jobs:
|
||||
path: app/build/reports/jacoco/jacocoTestReport/
|
||||
if-no-files-found: warn
|
||||
|
||||
# No-regression coverage gate (issue #251): fails CI if scoped LINE coverage regresses below the
|
||||
# floor pinned in app/build.gradle.kts. Runs after the upload so the HTML/XML report is always
|
||||
# archived for triage even when this step goes red.
|
||||
- name: Verify JaCoCo coverage (no-regression floor)
|
||||
if: ${{ !cancelled() }}
|
||||
run: ./gradlew :app:jacocoTestCoverageVerification --stacktrace
|
||||
|
||||
static-analysis:
|
||||
name: Static analysis
|
||||
needs: traffic-control # order after runner-priority orchestration (P0/broken preempt; P1–P9 hold-back)
|
||||
|
||||
Reference in New Issue
Block a user