diff --git a/.github/workflows/lint-fmt-core.yml b/.github/workflows/lint-fmt-core.yml index 741b22379..df952ad2d 100644 --- a/.github/workflows/lint-fmt-core.yml +++ b/.github/workflows/lint-fmt-core.yml @@ -50,7 +50,7 @@ jobs: clippy: - { args: '', key: 'empty' } - { - args: '--features compression,wry,linux-protocol-headers,isolation,custom-protocol,api-all,updater,system-tray', + args: '--features compression,wry,linux-protocol-headers,isolation,custom-protocol,api-all,system-tray', key: 'all' } - { args: '--features custom-protocol', key: 'custom-protocol' } diff --git a/.github/workflows/test-core.yml b/.github/workflows/test-core.yml index 9f60816af..f0526c7ef 100644 --- a/.github/workflows/test-core.yml +++ b/.github/workflows/test-core.yml @@ -76,7 +76,7 @@ jobs: key: api-all } - { - args: --features compression,wry,linux-protocol-headers,isolation,custom-protocol,api-all,updater,system-tray, + args: --features compression,wry,linux-protocol-headers,isolation,custom-protocol,api-all,system-tray, key: all } diff --git a/core/tauri-config-schema/schema.json b/core/tauri-config-schema/schema.json index 731da5884..58b4dccc9 100644 --- a/core/tauri-config-schema/schema.json +++ b/core/tauri-config-schema/schema.json @@ -86,6 +86,13 @@ "minimumSystemVersion": "10.13" }, "targets": "all", + "updater": { + "active": false, + "pubkey": "", + "windows": { + "installMode": "passive" + } + }, "windows": { "allowDowngrades": true, "certificateThumbprint": null, @@ -209,6 +216,13 @@ "minimumSystemVersion": "10.13" }, "targets": "all", + "updater": { + "active": false, + "pubkey": "", + "windows": { + "installMode": "passive" + } + }, "windows": { "allowDowngrades": true, "certificateThumbprint": null, @@ -783,6 +797,21 @@ "$ref": "#/definitions/AndroidConfig" } ] + }, + "updater": { + "description": "The updater configuration.", + "default": { + "active": false, + "pubkey": "", + "windows": { + "installMode": "passive" + } + }, + "allOf": [ + { + "$ref": "#/definitions/UpdaterConfig" + } + ] } }, "additionalProperties": false @@ -1400,6 +1429,76 @@ }, "additionalProperties": false }, + "UpdaterConfig": { + "description": "The Updater configuration object.\n\nSee more: https://tauri.app/v1/api/config#updaterconfig", + "type": "object", + "properties": { + "active": { + "description": "Whether the updater is active or not.", + "default": false, + "type": "boolean" + }, + "pubkey": { + "description": "Signature public key.", + "default": "", + "type": "string" + }, + "windows": { + "description": "The Windows configuration for the updater.", + "default": { + "installMode": "passive" + }, + "allOf": [ + { + "$ref": "#/definitions/UpdaterWindowsConfig" + } + ] + } + }, + "additionalProperties": false + }, + "UpdaterWindowsConfig": { + "description": "The updater configuration for Windows.\n\nSee more: https://tauri.app/v1/api/config#updaterwindowsconfig", + "type": "object", + "properties": { + "installMode": { + "description": "The installation mode for the update on Windows. Defaults to `passive`.", + "default": "passive", + "allOf": [ + { + "$ref": "#/definitions/WindowsUpdateInstallMode" + } + ] + } + }, + "additionalProperties": false + }, + "WindowsUpdateInstallMode": { + "description": "Install modes for the Windows update.", + "oneOf": [ + { + "description": "Specifies there's a basic UI during the installation process, including a final dialog box at the end.", + "type": "string", + "enum": [ + "basicUi" + ] + }, + { + "description": "The quiet mode means there's no user interaction required. Requires admin privileges if the installer does (WiX).", + "type": "string", + "enum": [ + "quiet" + ] + }, + { + "description": "Specifies unattended mode, which means the installation only shows a progress bar.", + "type": "string", + "enum": [ + "passive" + ] + } + ] + }, "AllowlistConfig": { "description": "Allowlist configuration. The allowlist is a translation of the [Cargo allowlist features](https://docs.rs/tauri/latest/tauri/#cargo-allowlist-features).\n\n# Notes\n\n- Endpoints that don't have their own allowlist option are enabled by default. - There is only \"opt-in\", no \"opt-out\". Setting an option to `false` has no effect.\n\n# Examples\n\n- * [`\"app-all\": true`](https://tauri.app/v1/api/config/#appallowlistconfig.all) will make the [hide](https://tauri.app/v1/api/js/app#hide) endpoint be available regardless of whether `hide` is set to `false` or `true` in the allowlist.", "type": "object", diff --git a/core/tauri-utils/src/config.rs b/core/tauri-utils/src/config.rs index 0c0efc933..21c1f7b3c 100644 --- a/core/tauri-utils/src/config.rs +++ b/core/tauri-utils/src/config.rs @@ -609,6 +609,65 @@ impl Default for WindowsConfig { } } +/// The Updater configuration object. +/// +/// See more: https://tauri.app/v1/api/config#updaterconfig +#[skip_serializing_none] +#[derive(Debug, PartialEq, Eq, Clone, Serialize)] +#[cfg_attr(feature = "schema", derive(JsonSchema))] +#[serde(rename_all = "camelCase", deny_unknown_fields)] +pub struct UpdaterConfig { + /// Whether the updater is active or not. + #[serde(default)] + pub active: bool, + /// Signature public key. + #[serde(default)] // use default just so the schema doesn't flag it as required + pub pubkey: String, + /// The Windows configuration for the updater. + #[serde(default)] + pub windows: UpdaterWindowsConfig, +} + +impl<'de> Deserialize<'de> for UpdaterConfig { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + #[derive(Deserialize)] + struct InnerUpdaterConfig { + #[serde(default)] + active: bool, + pubkey: Option, + #[serde(default)] + windows: UpdaterWindowsConfig, + } + + let config = InnerUpdaterConfig::deserialize(deserializer)?; + + if config.active && config.pubkey.is_none() { + return Err(DeError::custom( + "The updater `pubkey` configuration is required.", + )); + } + + Ok(UpdaterConfig { + active: config.active, + pubkey: config.pubkey.unwrap_or_default(), + windows: config.windows, + }) + } +} + +impl Default for UpdaterConfig { + fn default() -> Self { + Self { + active: false, + pubkey: "".into(), + windows: Default::default(), + } + } +} + /// Configuration for tauri-bundler. /// /// See more: https://tauri.app/v1/api/config#bundleconfig @@ -683,6 +742,9 @@ pub struct BundleConfig { /// Android configuration. #[serde(default)] pub android: AndroidConfig, + /// The updater configuration. + #[serde(default)] + pub updater: UpdaterConfig, } /// The window configuration object. @@ -1606,9 +1668,6 @@ impl<'de> Deserialize<'de> for WindowsUpdateInstallMode { #[cfg_attr(feature = "schema", derive(JsonSchema))] #[serde(rename_all = "camelCase", deny_unknown_fields)] pub struct UpdaterWindowsConfig { - /// Additional arguments given to the NSIS or WiX installer. - #[serde(default, alias = "installer-args")] - pub installer_args: Vec, /// The installation mode for the update on Windows. Defaults to `passive`. #[serde(default, alias = "install-mode")] pub install_mode: WindowsUpdateInstallMode, @@ -2343,6 +2402,16 @@ mod build { } } + impl ToTokens for UpdaterConfig { + fn to_tokens(&self, tokens: &mut TokenStream) { + let active = self.active; + let pubkey = str_lit(&self.pubkey); + let windows = &self.windows; + + literal_struct!(tokens, UpdaterConfig, active, pubkey, windows); + } + } + impl ToTokens for BundleConfig { fn to_tokens(&self, tokens: &mut TokenStream) { let identifier = str_lit(&self.identifier); @@ -2362,6 +2431,7 @@ mod build { let windows = &self.windows; let ios = quote!(Default::default()); let android = quote!(Default::default()); + let updater = quote!(Default::default()); literal_struct!( tokens, @@ -2382,7 +2452,8 @@ mod build { external_bin, windows, ios, - android + android, + updater ); } } @@ -2444,8 +2515,7 @@ mod build { impl ToTokens for UpdaterWindowsConfig { fn to_tokens(&self, tokens: &mut TokenStream) { let install_mode = &self.install_mode; - let installer_args = vec_lit(&self.installer_args, str_lit); - literal_struct!(tokens, UpdaterWindowsConfig, install_mode, installer_args); + literal_struct!(tokens, UpdaterWindowsConfig, install_mode); } } @@ -2696,6 +2766,7 @@ mod test { windows: Default::default(), ios: Default::default(), android: Default::default(), + updater: Default::default(), }, security: SecurityConfig { csp: None, diff --git a/core/tauri/src/app.rs b/core/tauri/src/app.rs index a69d8c29c..9179e2a5e 100644 --- a/core/tauri/src/app.rs +++ b/core/tauri/src/app.rs @@ -178,10 +178,7 @@ pub enum RunEvent { impl From for RunEvent { fn from(event: EventLoopMessage) -> Self { - match event { - #[cfg(updater)] - EventLoopMessage::Updater(event) => RunEvent::Updater(event), - } + match event {} } } diff --git a/examples/api/src-tauri/src/lib.rs b/examples/api/src-tauri/src/lib.rs index 2be465001..4552c29e8 100644 --- a/examples/api/src-tauri/src/lib.rs +++ b/examples/api/src-tauri/src/lib.rs @@ -59,10 +59,10 @@ pub fn run() { .shadow(true); } - let window = window_builder.build().unwrap(); + let _window = window_builder.build().unwrap(); #[cfg(debug_assertions)] - window.open_devtools(); + _window.open_devtools(); let value = Some("test".to_string()); let response = app.sample().ping(PingRequest { diff --git a/examples/api/src-tauri/tauri.conf.json b/examples/api/src-tauri/tauri.conf.json index 9cc0309a6..fb652c2bd 100644 --- a/examples/api/src-tauri/tauri.conf.json +++ b/examples/api/src-tauri/tauri.conf.json @@ -75,6 +75,13 @@ } } } + }, + "updater": { + "active": true, + "pubkey": "asdasd", + "windows": { + "installMode": "passive" + } } }, "allowlist": { diff --git a/tooling/bundler/src/bundle/settings.rs b/tooling/bundler/src/bundle/settings.rs index 7661cbe7d..03e028e58 100644 --- a/tooling/bundler/src/bundle/settings.rs +++ b/tooling/bundler/src/bundle/settings.rs @@ -137,8 +137,6 @@ pub struct PackageSettings { pub struct UpdaterSettings { /// Whether the updater is active or not. pub active: bool, - /// The updater endpoints. - pub endpoints: Option>, /// Signature public key. pub pubkey: String, /// Args to pass to `msiexec.exe` to run the updater on Windows. diff --git a/tooling/cli/schema.json b/tooling/cli/schema.json index 731da5884..58b4dccc9 100644 --- a/tooling/cli/schema.json +++ b/tooling/cli/schema.json @@ -86,6 +86,13 @@ "minimumSystemVersion": "10.13" }, "targets": "all", + "updater": { + "active": false, + "pubkey": "", + "windows": { + "installMode": "passive" + } + }, "windows": { "allowDowngrades": true, "certificateThumbprint": null, @@ -209,6 +216,13 @@ "minimumSystemVersion": "10.13" }, "targets": "all", + "updater": { + "active": false, + "pubkey": "", + "windows": { + "installMode": "passive" + } + }, "windows": { "allowDowngrades": true, "certificateThumbprint": null, @@ -783,6 +797,21 @@ "$ref": "#/definitions/AndroidConfig" } ] + }, + "updater": { + "description": "The updater configuration.", + "default": { + "active": false, + "pubkey": "", + "windows": { + "installMode": "passive" + } + }, + "allOf": [ + { + "$ref": "#/definitions/UpdaterConfig" + } + ] } }, "additionalProperties": false @@ -1400,6 +1429,76 @@ }, "additionalProperties": false }, + "UpdaterConfig": { + "description": "The Updater configuration object.\n\nSee more: https://tauri.app/v1/api/config#updaterconfig", + "type": "object", + "properties": { + "active": { + "description": "Whether the updater is active or not.", + "default": false, + "type": "boolean" + }, + "pubkey": { + "description": "Signature public key.", + "default": "", + "type": "string" + }, + "windows": { + "description": "The Windows configuration for the updater.", + "default": { + "installMode": "passive" + }, + "allOf": [ + { + "$ref": "#/definitions/UpdaterWindowsConfig" + } + ] + } + }, + "additionalProperties": false + }, + "UpdaterWindowsConfig": { + "description": "The updater configuration for Windows.\n\nSee more: https://tauri.app/v1/api/config#updaterwindowsconfig", + "type": "object", + "properties": { + "installMode": { + "description": "The installation mode for the update on Windows. Defaults to `passive`.", + "default": "passive", + "allOf": [ + { + "$ref": "#/definitions/WindowsUpdateInstallMode" + } + ] + } + }, + "additionalProperties": false + }, + "WindowsUpdateInstallMode": { + "description": "Install modes for the Windows update.", + "oneOf": [ + { + "description": "Specifies there's a basic UI during the installation process, including a final dialog box at the end.", + "type": "string", + "enum": [ + "basicUi" + ] + }, + { + "description": "The quiet mode means there's no user interaction required. Requires admin privileges if the installer does (WiX).", + "type": "string", + "enum": [ + "quiet" + ] + }, + { + "description": "Specifies unattended mode, which means the installation only shows a progress bar.", + "type": "string", + "enum": [ + "passive" + ] + } + ] + }, "AllowlistConfig": { "description": "Allowlist configuration. The allowlist is a translation of the [Cargo allowlist features](https://docs.rs/tauri/latest/tauri/#cargo-allowlist-features).\n\n# Notes\n\n- Endpoints that don't have their own allowlist option are enabled by default. - There is only \"opt-in\", no \"opt-out\". Setting an option to `false` has no effect.\n\n# Examples\n\n- * [`\"app-all\": true`](https://tauri.app/v1/api/config/#appallowlistconfig.all) will make the [hide](https://tauri.app/v1/api/js/app#hide) endpoint be available regardless of whether `hide` is set to `false` or `true` in the allowlist.", "type": "object", diff --git a/tooling/cli/src/build.rs b/tooling/cli/src/build.rs index b1271adca..0c449cf95 100644 --- a/tooling/cli/src/build.rs +++ b/tooling/cli/src/build.rs @@ -112,7 +112,7 @@ pub fn command(mut options: Options, verbosity: u8) -> Result<()> { }; if let Some(types) = &package_types { - if config_.tauri.updater.active && !types.contains(&PackageType::Updater) { + if config_.tauri.bundle.updater.active && !types.contains(&PackageType::Updater) { warn!("The updater is enabled but the bundle target list does not contain `updater`, so the updater artifacts won't be generated."); } } @@ -188,7 +188,7 @@ pub fn command(mut options: Options, verbosity: u8) -> Result<()> { .filter(|bundle| bundle.package_type == PackageType::Updater) .collect(); // If updater is active and we bundled it - if config_.tauri.updater.active && !updater_bundles.is_empty() { + if config_.tauri.bundle.updater.active && !updater_bundles.is_empty() { // if no password provided we use an empty string let password = var_os("TAURI_KEY_PASSWORD") .map(|v| v.to_str().unwrap().to_string()) @@ -211,7 +211,7 @@ pub fn command(mut options: Options, verbosity: u8) -> Result<()> { }?; let pubkey = - base64::engine::general_purpose::STANDARD.decode(&config_.tauri.updater.pubkey)?; + base64::engine::general_purpose::STANDARD.decode(&config_.tauri.bundle.updater.pubkey)?; let pub_key_decoded = String::from_utf8_lossy(&pubkey); let public_key = minisign::PublicKeyBox::from_string(&pub_key_decoded)?.into_public_key()?; diff --git a/tooling/cli/src/interface/rust.rs b/tooling/cli/src/interface/rust.rs index dff3f7214..f35d53c31 100644 --- a/tooling/cli/src/interface/rust.rs +++ b/tooling/cli/src/interface/rust.rs @@ -693,7 +693,6 @@ impl AppSettings for RustAppSettings { features, config.tauri.bundle.clone(), config.tauri.system_tray.clone(), - config.tauri.updater.clone(), ) } @@ -1029,7 +1028,6 @@ fn tauri_config_to_bundle_settings( features: &[String], config: crate::helpers::config::BundleConfig, system_tray_config: Option, - updater_config: crate::helpers::config::UpdaterConfig, ) -> crate::Result { let enabled_features = manifest.all_enabled_features(features); @@ -1159,12 +1157,9 @@ fn tauri_config_to_bundle_settings( allow_downgrades: config.windows.allow_downgrades, }, updater: Some(UpdaterSettings { - active: updater_config.active, - pubkey: updater_config.pubkey, - endpoints: updater_config - .endpoints - .map(|endpoints| endpoints.iter().map(|e| e.to_string()).collect()), - msiexec_args: Some(updater_config.windows.install_mode.msiexec_args()), + active: config.updater.active, + pubkey: config.updater.pubkey, + msiexec_args: Some(config.updater.windows.install_mode.msiexec_args()), }), ..Default::default() })