From ebfc751471da5972194169ac19a7c18da1e071e5 Mon Sep 17 00:00:00 2001 From: ospab Date: Thu, 30 Jul 2026 20:56:33 +0300 Subject: [PATCH] fix(android): treat a blank signing secret as absent, not as the password The Android jobs failed with "Get Key failed: Given final block not properly padded" once the store password was corrected - the keystore opened, but the KEY could not be decrypted. Cause: GitHub Actions substitutes an empty string, not an unset variable, for a secret that does not exist. ANDROID_KEY_PASSWORD is deliberately not set (our keystore is PKCS12, where the key password cannot differ from the store password), so OSTP_KEY_PASSWORD arrived as "". Kotlin's elvis operator only falls back on null, so `getenv(...) ?: storePassword` kept the empty string and used it as the literal key password. signingSetting() now maps blank to null, so the documented fallback actually happens. Applies to every signing field, not just the key password - the same trap would have hit any of them. --- ostp-flutter/android/app/build.gradle.kts | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/ostp-flutter/android/app/build.gradle.kts b/ostp-flutter/android/app/build.gradle.kts index 196485c..af7634c 100644 --- a/ostp-flutter/android/app/build.gradle.kts +++ b/ostp-flutter/android/app/build.gradle.kts @@ -26,8 +26,15 @@ val keystoreProperties = Properties().apply { } } +// Blank counts as absent. GitHub Actions substitutes an EMPTY STRING (not an +// unset variable) for a secret that doesn't exist, so `getenv(...) ?: fallback` +// silently kept the empty value — the elvis operator only catches null. That is +// how an unset ANDROID_KEY_PASSWORD ended up being used as the literal key +// password instead of falling back to the store password, producing Gradle's +// "Get Key failed: Given final block not properly padded". fun signingSetting(propKey: String, envKey: String): String? = - keystoreProperties.getProperty(propKey) ?: System.getenv(envKey) + (keystoreProperties.getProperty(propKey) ?: System.getenv(envKey)) + ?.takeIf { it.isNotBlank() } val releaseStorePath: String? = signingSetting("storeFile", "OSTP_KEYSTORE_PATH") val hasReleaseSigning: Boolean = !releaseStorePath.isNullOrBlank()