From 61713703f83c9d222e1abe50b73fea220d37dfbd Mon Sep 17 00:00:00 2001 From: Dark-Avery Date: Mon, 16 Mar 2026 23:30:08 +0300 Subject: [PATCH] build(android): add env-based release signing config --- .gitignore | 3 ++ android/app/build.gradle.kts | 58 ++++++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+) diff --git a/.gitignore b/.gitignore index 28c6140..d523b6d 100644 --- a/.gitignore +++ b/.gitignore @@ -24,6 +24,9 @@ local.properties android/.idea/ android/build/ android/app/build/ +android/*.jks +android/*.keystore +android/*.keystore.properties # OS Thumbs.db diff --git a/android/app/build.gradle.kts b/android/app/build.gradle.kts index 18b3f4a..7fdacff 100644 --- a/android/app/build.gradle.kts +++ b/android/app/build.gradle.kts @@ -1,4 +1,6 @@ import org.gradle.api.tasks.Sync +import org.gradle.api.GradleException +import java.io.File plugins { id("com.android.application") @@ -6,6 +8,44 @@ plugins { id("org.jetbrains.kotlin.android") } +data class ReleaseSigningEnv( + val keystoreFile: File, + val storePassword: String, + val keyAlias: String, + val keyPassword: String, +) + +fun requiredEnv(name: String): String { + return System.getenv(name)?.takeIf { it.isNotBlank() } + ?: throw GradleException("Missing required environment variable: $name") +} + +fun loadReleaseSigningEnv(releaseSigningRequested: Boolean): ReleaseSigningEnv? { + val keystorePath = System.getenv("ANDROID_KEYSTORE_FILE")?.takeIf { it.isNotBlank() } + val anySigningEnvProvided = listOf( + keystorePath, + System.getenv("ANDROID_KEYSTORE_PASSWORD"), + System.getenv("ANDROID_KEY_ALIAS"), + System.getenv("ANDROID_KEY_PASSWORD"), + ).any { !it.isNullOrBlank() } + + if (!releaseSigningRequested && !anySigningEnvProvided) { + return null + } + + val keystoreFile = File(requiredEnv("ANDROID_KEYSTORE_FILE")) + if (!keystoreFile.isFile) { + throw GradleException("ANDROID_KEYSTORE_FILE does not exist: ${keystoreFile.absolutePath}") + } + + return ReleaseSigningEnv( + keystoreFile = keystoreFile, + storePassword = requiredEnv("ANDROID_KEYSTORE_PASSWORD"), + keyAlias = requiredEnv("ANDROID_KEY_ALIAS"), + keyPassword = requiredEnv("ANDROID_KEY_PASSWORD"), + ) +} + val stagedPythonSourcesDir = layout.buildDirectory.dir("generated/chaquopy/python") val stagePythonSources by tasks.registering(Sync::class) { from(rootProject.projectDir.resolve("../proxy")) { @@ -13,6 +53,10 @@ val stagePythonSources by tasks.registering(Sync::class) { } into(stagedPythonSourcesDir) } +val releaseSigningRequested = gradle.startParameter.taskNames.any { + it.contains("release", ignoreCase = true) +} +val releaseSigningEnv = loadReleaseSigningEnv(releaseSigningRequested) android { namespace = "org.flowseal.tgwsproxy" @@ -32,6 +76,17 @@ android { } } + signingConfigs { + if (releaseSigningEnv != null) { + create("release") { + storeFile = releaseSigningEnv.keystoreFile + storePassword = releaseSigningEnv.storePassword + keyAlias = releaseSigningEnv.keyAlias + keyPassword = releaseSigningEnv.keyPassword + } + } + } + buildTypes { release { isMinifyEnabled = false @@ -39,6 +94,9 @@ android { getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro", ) + if (releaseSigningEnv != null) { + signingConfig = signingConfigs.getByName("release") + } } }