feat(release): m6 release mechanics — signed APK, R8, version guard, icons #11
Reference in New Issue
Block a user
No description provided.
Delete Branch "feat/m6-release"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
M6 — Polish & first release (release mechanics)
Release-hardening pass per
docs/android/PLAN.md§9 (M6), §10, §12. No architecture, data-flow, endpoint, or DTO changes — the app stays a pure API client. Biometric app-lock is descoped (out of v1 unless later requested; tokens are already encrypted at rest).App icons (default brand assets)
@color/ic_launcher_background#1B1033), and recomposited the legacy square/round webps + the 512 Play icon over indigo so the whole set is coherent (the green never ships).<monochrome>layer — the full-colour medallion has no clean single-tone silhouette, so themed-icon mode falls back to the standard icon rather than a tinted blob.Version-mismatch guard (§3)
v2) with a clear "app is out of date" message, instead of mis-rendering. Lenient on a blankapi(older backend). Decision logic extracted to a pureConnectionRepository.evaluateVersion()with unit tests.Release build hardening (§7, §12)
-dontwarnfor Tink's compile-only Error Prone annotations (fromEncryptedSharedPreferences).signingConfigreads keystore material from a gitignoredkeystore.propertiesor env vars; absent → unsigned (debug builds + the PR gate are unaffected, so contributors without the keystore still build). The keystore never lives in the repo.versionNameis the committed source of truth (bumped by the release engine);versionCodeis derived from it (major*10000+minor*100+patch, monotonic). Both stay-P-overridable for local builds (§10).CI — auto-release engine (mirrors
link/)release.ymlislink/'s language-agnostic release engine adapted for Android. On every push tomainit: derives the next version from conventional-commit subjects since the lastv*tag (feat!/BREAKING → major,feat→ minor,fix/perf→ patch; nothing releasable → no release), generates a grouped changelog, bumpsbuild.gradle.kts, builds the signed APK (keystore from a base64 Gitea secret), then commits the bump[skip ci], tagsvX.Y.Z, and creates the Gitea release with notes + APK +SHA256SUMS.REGISTRY_USER/REGISTRY_TOKEN(write:repository) to push the bump + create the release, exactly likelink/;mainmust allow that account to push. Mirrorspr-checks.yml's self-hosted-runner handling (apt JDK 17, explicitsdkmanager, in-stepchmod +x gradlew).Verification
:app:testDebugUnitTest+:app:lintDebug+:app:assembleReleasegreen. The release APK is signed (verified v2 scheme, cert matches the generated upload keystore) and version overrides flow into the manifest. The release-engine shell logic (version extract, bump,versionCodederive, the twobuild.gradle.ktsseds) was validated against the real file.release.ymlcan publish, add repo Actions secrets:REGISTRY_USER,REGISTRY_TOKEN(write:repository),ANDROID_KEYSTORE_BASE64,ANDROID_KEYSTORE_PASSWORD,ANDROID_KEY_ALIAS,ANDROID_KEY_PASSWORD— and allow that account to push tomain. Handed off separately.mainauto-cuts a release (the first run, with no priorv*tag, ships the committed0.1.0). The on-device visual QA item carried over from M5 still applies before shipping publicly.AI disclosure
AI-assisted (Claude Code). AI-authored commits carry
Co-Authored-By: Claude <noreply@anthropic.com>.