From 7d5bd44791a7e769ca209e5441e8488aac324ed6 Mon Sep 17 00:00:00 2001 From: Fontlos <56759523+fontlos@users.noreply.github.com> Date: Thu, 8 May 2025 05:22:59 +0800 Subject: [PATCH] feat(cli): add `bundle.android` config to build and sign the apk file in release mode (#4062) * feat(cli): add `bundle.android` config to build and sign the apk file in release mode Add this to `Dioxus.toml` ```toml [bundle.android] jks_file = "path/to/jks file relative to Dioxus.toml" jks_password = "jks_password " key_alias = "key_alias" key_password = "key_password " ``` When release flag is enabled and this configuration exists at the same time, use `gradlew assembleRelease` build and sign apk file * fix merge conflict * only run assembleRelease when bundle exists --------- Co-authored-by: Jonathan Kelley --- .../assets/android/gen/app/build.gradle.kts.hbs | 15 ++++++++++++++- packages/cli/src/build/request.rs | 11 ++++++++++- packages/cli/src/config/bundle.rs | 10 ++++++++++ 3 files changed, 34 insertions(+), 2 deletions(-) diff --git a/packages/cli/assets/android/gen/app/build.gradle.kts.hbs b/packages/cli/assets/android/gen/app/build.gradle.kts.hbs index 74ac21707..882e4ff85 100644 --- a/packages/cli/assets/android/gen/app/build.gradle.kts.hbs +++ b/packages/cli/assets/android/gen/app/build.gradle.kts.hbs @@ -13,6 +13,16 @@ android { versionCode = 1 versionName = "1.0" } + {{#if android_bundle}} + signingConfigs { + create("release") { + storeFile = file("../../../../../../../{{ android_bundle.jks_file }}") + storePassword = "{{ android_bundle.jks_password }}" + keyAlias = "{{ android_bundle.key_alias }}" + keyPassword = "{{ android_bundle.key_password }}" + } + } + {{/if}} buildTypes { getByName("debug") { isDebuggable = true @@ -27,7 +37,10 @@ android { } getByName("release") { isMinifyEnabled = true - proguardFiles( + {{#if android_bundle}} + signingConfig = signingConfigs.getByName("release") + {{/if}} + proguardFiles( *fileTree(".") { include("**/*.pro") } .plus(getDefaultProguardFile("proguard-android-optimize.txt")) .toList().toTypedArray() diff --git a/packages/cli/src/build/request.rs b/packages/cli/src/build/request.rs index b024bc466..6251f39fe 100644 --- a/packages/cli/src/build/request.rs +++ b/packages/cli/src/build/request.rs @@ -2271,10 +2271,12 @@ session_cache_dir: {}"#, struct AndroidHandlebarsObjects { application_id: String, app_name: String, + android_bundle: Option, } let hbs_data = AndroidHandlebarsObjects { application_id: self.full_mobile_app_name(), app_name: self.bundled_app_name(), + android_bundle: self.config.bundle.android.clone(), }; let hbs = handlebars::Handlebars::new(); @@ -3164,8 +3166,15 @@ session_cache_dir: {}"#, if let Platform::Android = self.platform { ctx.status_running_gradle(); + // When the build mode is set to release and there is an Android signature configuration, use assembleRelease + let build_type = if self.release && self.config.bundle.android.is_some() { + "assembleRelease" + } else { + "assembleDebug" + }; + let output = Command::new(self.gradle_exe()?) - .arg("assembleDebug") + .arg(build_type) .current_dir(self.root_dir()) .output() .await?; diff --git a/packages/cli/src/config/bundle.rs b/packages/cli/src/config/bundle.rs index 042dd2022..8508e1cf3 100644 --- a/packages/cli/src/config/bundle.rs +++ b/packages/cli/src/config/bundle.rs @@ -16,6 +16,7 @@ pub(crate) struct BundleConfig { pub(crate) deb: Option, pub(crate) macos: Option, pub(crate) windows: Option, + pub(crate) android: Option, } #[derive(Debug, Clone, Serialize, Deserialize, Default)] @@ -185,6 +186,15 @@ impl Default for WebviewInstallMode { } } +// Because all four fields must appear at the same time, there is no need for an Option +#[derive(Debug, Clone, Serialize, Deserialize)] +pub(crate) struct AndroidSettings { + pub(crate) jks_file: PathBuf, + pub(crate) jks_password: String, + pub(crate) key_alias: String, + pub(crate) key_password: String, +} + #[derive(Debug, Clone, Serialize, Deserialize)] pub struct CustomSignCommandSettings { /// The command to run to sign the binary.