Merge pull request 'docs(android): record SonarQube coverage wiring and issue triage (§12.1)' (#39) from docs/android-sonar-coverage into main

Reviewed-on: #39
Reviewed-by: Colby Whitlock <whitlocktech@gmail.com>
This commit is contained in:
2026-07-22 19:00:35 +00:00

View File

@@ -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