2500914498
Update installs were failing at the system scanner step because every
release APK was signed with a different signature: build.gradle.kts
fell back to signingConfigs.getByName("debug"), and the debug
keystore is generated per-machine — so every CI runner had a fresh
random key. Android refuses to upgrade an installed app when the
signature doesn't match, hence the "App not installed" failure
after the scan.
Two-part fix:
1. build.gradle.kts now defines a real "release" signing config when
ANDROID_KEYSTORE_PATH is exported (with the matching password +
alias env vars). Without those, falls through to the debug
keystore so local `flutter run --release` still works.
2. flutter.yml decodes ANDROID_KEYSTORE_B64 (CI secret, base64 of the
real release keystore) into a tmp path before the release-APK
build step, then exports ANDROID_KEYSTORE_PATH + the three
password/alias secrets as env vars. CI now hard-errors if the
keystore secret is missing on a tagged build — we don't want
another silent debug-keystore release.
OPERATOR ACTION REQUIRED before the next tag:
1. Generate a release keystore (one-time):
keytool -genkey -v -keystore minstrel-release.keystore \
-alias minstrel -keyalg RSA -keysize 2048 -validity 10000
2. Base64 it:
base64 -w0 minstrel-release.keystore > keystore.b64
3. In Forgejo, add four repo secrets:
ANDROID_KEYSTORE_B64 = contents of keystore.b64
ANDROID_KEY_ALIAS = minstrel
ANDROID_STORE_PASSWORD = the password you set
ANDROID_KEY_PASSWORD = same password (or different alias pwd)
4. Keep minstrel-release.keystore offline and backed up — losing it
means you can never sign an upgrade for any existing install.
5. Existing installs from prior debug-keyed releases must be
uninstalled before installing the first key-signed release. This
is a one-time transition; future tagged builds will upgrade
cleanly.