Adding Android Lint to CI immediately caught two real crash bugs invisible to
all emulator QA (the fixture emulators run API 34+):
- SettingsViewModel + YourProgressViewModel called LocalDate.ofInstant, which
was only added in API 34 — but minSdk is 26. On every device running Android
8-13 (the bulk of the install base) these throw NoSuchMethodError and crash
the Settings and Your Progress screens. Fixed with the API-26-safe equivalent
Instant.atZone(zone).toLocalDate() (same result).
The other two Lint errors were false positives (ProduceStateDoesNotAssignValue
on two EncryptedChatImage composables that DO assign value inside the producer —
the check misfires on a suspend/?.let RHS) — explicitly @Suppress'd with a note,
so Lint reaches 0 errors legitimately rather than via a blanket baseline.
CI (android-ci.yml) gains two jobs:
- android-lint: ./gradlew :app:lintDebug (fails on error-severity; 113 existing
warnings are non-fatal and left for a separate burndown).
- release-build: first-ever R8 gate — builds :app:bundleRelease with a throwaway
keystore + dummy RC_API_KEY (satisfies the release guards; AAB not distributed),
so the minify/shrink/sign toolchain can never silently rot. Verified locally:
bundleRelease SUCCEEDS today (95MB AAB). A green build proves the toolchain,
not runtime survival of reflectively-loaded classes (Tink) — that stays a
release-APK QA item.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>