feat(release): m6 release mechanics — signed APK, R8, version guard, icons
All checks were successful
PR Checks / android-build (pull_request) Successful in 9m52s

Release-hardening pass (PLAN.md §9 M6, §10, §12). No architecture, data-flow,
or endpoint changes; the app remains a pure API client.

App icons (default brand assets):
- New gateway-medallion launcher icon set (all densities, adaptive fg/bg, round,
  Play Store icon) + an RG notification icon staged for M7 push.
- Replace the Image Asset wizard's default green-grid adaptive background with the
  deep-indigo brand fill (@color/ic_launcher_background #1B1033); recomposite the
  legacy square/round webps and the 512 Play icon over indigo so the whole set is
  coherent (the green never shipped). Restore the SPDX headers the wizard stripped;
  drop the orphaned placeholder foreground vector. No <monochrome> layer — the
  full-colour medallion has no clean silhouette, so themed mode falls back to the
  standard icon rather than a tinted blob.

Version-mismatch guard (§3):
- The connect probe now refuses a Runic Gateway backend whose API version this
  build can't speak (e.g. a future v2) with a clear "app out of date" message,
  instead of mis-rendering; lenient on a blank api (older backend). Decision logic
  extracted to a pure ConnectionRepository.evaluateVersion() with unit tests.

Release build hardening (§7, §12):
- Enable R8 full-mode minify + resource shrink for release (~31 MB debug -> 4.2 MB
  signed release). ProGuard keep-rules for kotlinx.serialization serializers + our
  wire DTOs, Retrofit service interfaces, and a -dontwarn for Tink's compile-only
  Error Prone annotations (EncryptedSharedPreferences).
- Release signingConfig reads keystore material from a gitignored keystore.properties
  or env vars; absent -> unsigned (debug + PR gate unaffected). Keystore never in repo.
- versionName/versionCode overridable via -P so the release tag + CI run number
  drive them (§10).

CI:
- release.yml: on a `v*` tag, build a SIGNED release APK (keystore from a base64
  Gitea secret) and attach it + SHA256SUMS to a Gitea release; workflow_dispatch is
  a signing dry run. Mirrors pr-checks.yml's self-hosted-runner handling (apt JDK 17,
  explicit sdkmanager, in-step chmod +x gradlew).

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2026-07-20 03:35:06 -05:00
parent e497e6c8a7
commit 0df862a6af
33 changed files with 408 additions and 33 deletions

View File

@@ -1,7 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- SPDX-License-Identifier: GPL-3.0-or-later -->
<!--
Adaptive launcher icon (API 26+, which is every target device at minSdk 29):
the gateway-medallion foreground (transparent PNG, all densities) over the
deep-indigo background. No <monochrome> layer: the medallion is a full-colour
mark that does not reduce to a clean single-tone silhouette, so themed-icon
mode falls back to this standard icon rather than a tinted blob.
-->
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/ic_launcher_background" />
<foreground android:drawable="@drawable/ic_launcher_foreground" />
<monochrome android:drawable="@drawable/ic_launcher_foreground" />
<background android:drawable="@drawable/ic_launcher_background" />
<foreground android:drawable="@mipmap/ic_launcher_foreground" />
</adaptive-icon>