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>
19
app/src/main/res/drawable-anydpi/ic_stat_name.xml
Normal file
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="172"
|
||||
android:viewportHeight="218.95209"
|
||||
android:tint="#FFFFFF">
|
||||
<group android:scaleX="0.7227152"
|
||||
android:scaleY="0.92"
|
||||
android:translateX="23.846495"
|
||||
android:translateY="8.758083">
|
||||
<group android:translateY="154.51205">
|
||||
<path android:pathData="M9.28125,-0L9.28125,-103.109375L42.265625,-103.109375Q53.140625,-103.109375,60.984375,-99.25Q68.828125,-95.40625,73.109375,-88.203125Q77.40625,-81,77.40625,-71.203125L77.40625,-70.0625Q77.40625,-60.1875,73.109375,-53.015625Q68.828125,-45.859375,60.9375,-41.96875Q53.0625,-38.09375,42.265625,-38.09375L20.296875,-38.09375L20.296875,-54.5L41.828125,-54.5Q49.46875,-54.5,53.75,-58.390625Q58.03125,-62.28125,58.03125,-69.125L58.03125,-70.984375Q58.03125,-77.828125,53.75,-81.71875Q49.46875,-85.609375,41.828125,-85.609375L28.4375,-85.609375L28.4375,-0L9.28125,-0ZM61.78125,-0L35.5625,-45.359375L56.65625,-45.359375L83.453125,-0L61.78125,-0Z"
|
||||
android:fillColor="#000000"/>
|
||||
<path android:pathData="M132.65625,2.375Q119.765625,2.375,110.40625,-3.921875Q101.046875,-10.21875,96.046875,-21.953125Q91.046875,-33.703125,91.046875,-49.96875L91.046875,-52.625Q91.046875,-69.046875,96.046875,-80.890625Q101.046875,-92.734375,110.296875,-99.109375Q119.546875,-105.484375,132.375,-105.484375Q145.25,-105.484375,153.96875,-99.109375Q162.6875,-92.734375,166.5625,-80.5L149.21875,-74.09375Q147.125,-81,143.04688,-84.234375Q138.98438,-87.484375,132.57812,-87.484375Q121.859375,-87.484375,116.125,-78.546875Q110.40625,-69.625,110.40625,-52.984375L110.40625,-49.609375Q110.40625,-32.96875,116.15625,-24.21875Q121.921875,-15.484375,132.79688,-15.484375Q141.57812,-15.484375,146.35938,-21.453125Q151.15625,-27.4375,151.15625,-38.453125L151.15625,-41.828125L129.84375,-41.828125L129.84375,-57.890625L169.09375,-57.890625L169.09375,-41.90625Q169.09375,-20.734375,159.57812,-9.171875Q150.07812,2.375,132.65625,2.375Z"
|
||||
android:fillColor="#000000"/>
|
||||
</group>
|
||||
</group>
|
||||
</vector>
|
||||
BIN
app/src/main/res/drawable-hdpi/ic_stat_name.png
Normal file
|
After Width: | Height: | Size: 493 B |
BIN
app/src/main/res/drawable-mdpi/ic_stat_name.png
Normal file
|
After Width: | Height: | Size: 352 B |
BIN
app/src/main/res/drawable-xhdpi/ic_stat_name.png
Normal file
|
After Width: | Height: | Size: 647 B |
BIN
app/src/main/res/drawable-xxhdpi/ic_stat_name.png
Normal file
|
After Width: | Height: | Size: 975 B |
17
app/src/main/res/drawable/ic_launcher_background.xml
Normal file
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- SPDX-License-Identifier: GPL-3.0-or-later -->
|
||||
<!--
|
||||
Adaptive-icon background layer (M6): a solid deep-indigo fill behind the
|
||||
transparent gateway-medallion foreground. Replaces the Image Asset wizard's
|
||||
default green grid. Sourced from @color/ic_launcher_background so the launcher
|
||||
background stays a single source of truth.
|
||||
-->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="108dp"
|
||||
android:height="108dp"
|
||||
android:viewportWidth="108"
|
||||
android:viewportHeight="108">
|
||||
<path
|
||||
android:fillColor="@color/ic_launcher_background"
|
||||
android:pathData="M0,0h108v108h-108z" />
|
||||
</vector>
|
||||
@@ -1,15 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- SPDX-License-Identifier: GPL-3.0-or-later -->
|
||||
<!-- Placeholder launcher glyph: a stylized gateway arch. Replaced in the M5 design pass. -->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="108dp"
|
||||
android:height="108dp"
|
||||
android:viewportWidth="108"
|
||||
android:viewportHeight="108">
|
||||
<path
|
||||
android:fillColor="#D0BCFF"
|
||||
android:pathData="M38,74 L38,50 A16,16 0 0,1 70,50 L70,74 L62,74 L62,50 A8,8 0 0,0 46,50 L46,74 Z" />
|
||||
<path
|
||||
android:fillColor="#EFB8C8"
|
||||
android:pathData="M52,34 L56,34 L56,40 L52,40 Z M50,40 L58,40 L58,44 L50,44 Z" />
|
||||
</vector>
|
||||
@@ -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>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- SPDX-License-Identifier: GPL-3.0-or-later -->
|
||||
<!-- Round adaptive launcher icon — same layers as ic_launcher.xml. -->
|
||||
<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>
|
||||
|
||||
BIN
app/src/main/res/mipmap-hdpi/ic_launcher.webp
Normal file
|
After Width: | Height: | Size: 3.9 KiB |
BIN
app/src/main/res/mipmap-hdpi/ic_launcher_foreground.webp
Normal file
|
After Width: | Height: | Size: 20 KiB |
BIN
app/src/main/res/mipmap-hdpi/ic_launcher_round.webp
Normal file
|
After Width: | Height: | Size: 4.5 KiB |
BIN
app/src/main/res/mipmap-mdpi/ic_launcher.webp
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
BIN
app/src/main/res/mipmap-mdpi/ic_launcher_foreground.webp
Normal file
|
After Width: | Height: | Size: 9.1 KiB |
BIN
app/src/main/res/mipmap-mdpi/ic_launcher_round.webp
Normal file
|
After Width: | Height: | Size: 2.3 KiB |
BIN
app/src/main/res/mipmap-xhdpi/ic_launcher.webp
Normal file
|
After Width: | Height: | Size: 6.5 KiB |
BIN
app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.webp
Normal file
|
After Width: | Height: | Size: 30 KiB |
BIN
app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp
Normal file
|
After Width: | Height: | Size: 7.3 KiB |
BIN
app/src/main/res/mipmap-xxhdpi/ic_launcher.webp
Normal file
|
After Width: | Height: | Size: 13 KiB |
BIN
app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.webp
Normal file
|
After Width: | Height: | Size: 61 KiB |
BIN
app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp
Normal file
|
After Width: | Height: | Size: 21 KiB |
BIN
app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.webp
Normal file
|
After Width: | Height: | Size: 106 KiB |
BIN
app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp
Normal file
|
After Width: | Height: | Size: 26 KiB |
@@ -30,6 +30,7 @@
|
||||
<string name="connect_error_scheme">Only http and https addresses are supported.</string>
|
||||
<string name="connect_error_insecure">A secure https address is required.</string>
|
||||
<string name="connect_error_not_runic">That site isn\'t a Runic Gateway shard.</string>
|
||||
<string name="connect_error_version">This app is out of date for that site (it speaks API %1$s). Update the app and try again.</string>
|
||||
<string name="connect_error_unreachable">Couldn\'t reach that site. Check the address and your connection.</string>
|
||||
<string name="connect_error_server">The site responded with an error (%1$d). Try again shortly.</string>
|
||||
|
||||
|
||||