docs(android): record SonarQube coverage wiring and issue triage (§12.1)
Add §12.1 documenting the Android-app SonarQube setup: the coverage gate failed at 0% because the source-only scan received no JaCoCo report (a reporting gap, not a testing gap). Records the JaCoCo wiring (jacoco plugin + report task, sonar.coverage.jacoco.xmlReportPaths, pure-UI coverage exclusions, a Gradle step in sonarqube.yml) and the 2026-07-22 triage: 3 smells fixed in code, 12 marked Won't Fix (snake_case DTO fields that mirror the wire contract; idiomatic Compose/nav complexity). Pairs with RunicGateway/Android-app chore/sonar-coverage-and-cleanup. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NgyHnrNa8WwG3doxvxjuCr
This commit is contained in:
@@ -995,6 +995,29 @@ repos use), on a bare `ubuntu:latest` container.
|
|||||||
signing identity stable from the first release (Play later requires consistency).
|
signing identity stable from the first release (Play later requires consistency).
|
||||||
- Semantic `versionName` + monotonic `versionCode`; tag releases.
|
- Semantic `versionName` + monotonic `versionCode`; tag releases.
|
||||||
|
|
||||||
|
### 12.1 Code quality — SonarQube (`Runic-Gateway-Android-app`)
|
||||||
|
|
||||||
|
Analysis runs post-merge and non-blocking (`.gitea/workflows/sonarqube.yml`); the gate is
|
||||||
|
informational. The project is clean (0 bugs / 0 vulns / 0 hotspots, Maintainability **A**); the only
|
||||||
|
gate failure is **coverage = 0% on new code**, which is a *reporting* gap, not a testing gap — the
|
||||||
|
25-file JVM unit suite exists, but the source-only Sonar scan never received a JaCoCo report.
|
||||||
|
|
||||||
|
**Coverage wiring (the fix):**
|
||||||
|
- Apply the `jacoco` plugin in `app/build.gradle.kts` + a `jacocoTestReport` task fed by
|
||||||
|
`testDebugUnitTest`, emitting XML. Exclude generated/DI/Compose scaffolding
|
||||||
|
(`**/*_Hilt*`, `**/*_Factory*`, `**/di/**`, `**/*ComposableSingletons*`, `R`/`BuildConfig`).
|
||||||
|
- `sonar-project.properties`: set `sonar.coverage.jacoco.xmlReportPaths` to the report, and
|
||||||
|
`sonar.coverage.exclusions` for pure-`@Composable` UI (JVM unit tests can't execute composable
|
||||||
|
bodies without Robolectric, so counting those lines would unfairly sink new-code coverage).
|
||||||
|
- `sonarqube.yml` must now run a real Gradle build before the scan (JDK 17 + Android SDK, mirroring
|
||||||
|
`pr-checks.yml`): `./gradlew testDebugUnitTest jacocoTestReport` → then the scan step.
|
||||||
|
|
||||||
|
**Issue triage (2026-07-22):** of 15 code smells, **3 fixed in code** — remove an unused import
|
||||||
|
(`AdminContentScreen.kt`), remove an unused `page` param (`AdminSupportScreen.RespondDialog`), and
|
||||||
|
decompose `LoginViewModel` (cognitive complexity 20). The remaining **12 marked *Won't Fix*** via the
|
||||||
|
Sonar API with rationale: 5 snake_case DTO fields (intentionally mirror the JSON wire contract) and 7
|
||||||
|
Compose/nav cognitive-complexity + hoisted-callback param-count smells (idiomatic for Jetpack Compose).
|
||||||
|
|
||||||
## 13. Open questions (revisit as we go)
|
## 13. Open questions (revisit as we go)
|
||||||
|
|
||||||
**Decided (recorded here for context):** single shard per install (§3); native auth is
|
**Decided (recorded here for context):** single shard per install (§3); native auth is
|
||||||
|
|||||||
Reference in New Issue
Block a user