Skip to content

Commit

Permalink
feat: add upgradeCode config option (#11039)
Browse files Browse the repository at this point in the history
* feat: add `upgradeCode` config option

* fix build on other platforms

* Update crates/tauri-bundler/src/bundle/settings.rs [skip ci]

* move to subcommand, use same product name fallback as the bundler

---------

Co-authored-by: Lucas Fernandes Nogueira <lucas@tauri.app>
  • Loading branch information
amrbashir and lucasfernog authored Sep 20, 2024
1 parent 3f1a8a4 commit f57a729
Show file tree
Hide file tree
Showing 14 changed files with 131 additions and 8 deletions.
6 changes: 6 additions & 0 deletions .changes/tauri-cli-generate-upgrade-code.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"tauri-cli": "patch:feat"
"@tauri-apps/cli": "patch:feat"
---

Add `tauri inspect wix-upgrade-code` to print default Upgrade Code for your MSI installer derived from `productName`.
6 changes: 6 additions & 0 deletions .changes/upgrade-code-option.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"tauri-utils": "patch:feat"
"tauri-bundler": "patch:feat"
---

Add `upgradeCode` in `wix` configuration to set an upgrade code for your MSI installer. This is recommended to be set if you plan to change your `productName`.
4 changes: 4 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion crates/tauri-bundler/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,9 @@ sha2 = "0.10"
zip = { version = "2.0", default-features = false, features = ["deflate"] }
dunce = "1"
url = "2"
uuid = { version = "1", features = ["v4", "v5"] }

[target."cfg(target_os = \"windows\")".dependencies]
uuid = { version = "1", features = ["v4", "v5"] }
bitness = "0.4"
windows-registry = "0.2.0"
glob = "0.3"
Expand Down
9 changes: 9 additions & 0 deletions crates/tauri-bundler/src/bundle/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,15 @@ impl Default for WixLanguage {
/// Settings specific to the WiX implementation.
#[derive(Clone, Debug, Default)]
pub struct WixSettings {
/// A GUID upgrade code for MSI installer. This code **_must stay the same across all of your updates_**,
/// otherwise, Windows will treat your update as a different app and your users will have duplicate versions of your app.
///
/// By default, tauri generates this code by generating a Uuid v5 using the string `<productName>.exe.app.x64` in the DNS namespace.
/// You can use Tauri's CLI to generate and print this code for you by running `tauri inspect wix-upgrade-code`.
///
/// It is recommended that you set this value in your tauri config file to avoid accidental changes in your upgrade code
/// whenever you want to change your product name.
pub upgrade_code: Option<uuid::Uuid>,
/// The app languages to build. See <https://docs.microsoft.com/en-us/windows/win32/msi/localizing-the-error-and-actiontext-tables>.
pub language: WixLanguage,
/// By default, the bundler uses an internal template.
Expand Down
20 changes: 14 additions & 6 deletions crates/tauri-bundler/src/bundle/windows/msi/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -548,13 +548,21 @@ pub fn build_wix_app_installer(
.unwrap_or_else(|| bundle_id.split('.').nth(1).unwrap_or(bundle_id));
data.insert("bundle_id", to_json(bundle_id));
data.insert("manufacturer", to_json(manufacturer));
let upgrade_code = Uuid::new_v5(
&Uuid::NAMESPACE_DNS,
format!("{}.exe.app.x64", &settings.product_name()).as_bytes(),
)
.to_string();

data.insert("upgrade_code", to_json(upgrade_code.as_str()));
// NOTE: if this is ever changed, make sure to also update `tauri inspect wix-upgrade-code` subcommand
let upgrade_code = settings
.windows()
.wix
.as_ref()
.and_then(|w| w.upgrade_code)
.unwrap_or_else(|| {
Uuid::new_v5(
&Uuid::NAMESPACE_DNS,
format!("{}.exe.app.x64", &settings.product_name()).as_bytes(),
)
});
data.insert("upgrade_code", to_json(upgrade_code.to_string()));

let product_code = Uuid::new_v5(
&Uuid::NAMESPACE_DNS,
settings.bundle_identifier().as_bytes(),
Expand Down
1 change: 1 addition & 0 deletions crates/tauri-cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ walkdir = "2"
elf = "0.7"
memchr = "2"
tempfile = "3"
uuid = { version = "1", features = ["v5"] }

[dev-dependencies]
insta = "1"
Expand Down
8 changes: 8 additions & 0 deletions crates/tauri-cli/config.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -2170,6 +2170,14 @@
"description": "Configuration for the MSI bundle using WiX.\n\n See more: <https://tauri.app/v1/api/config#wixconfig>",
"type": "object",
"properties": {
"upgradeCode": {
"description": "A GUID upgrade code for MSI installer. This code **_must stay the same across all of your updates_**,\n otherwise, Windows will treat your update as a different app and your users will have duplicate versions of your app.\n\n By default, tauri generates this code by generating a Uuid v5 using the string `<productName>.exe.app.x64` in the DNS namespace.\n You can use Tauri's CLI to generate and print this code for you, run `tauri inspect wix-upgrade-code`.\n\n It is recommended that you set this value in your tauri config file to avoid accidental changes in your upgrade code\n whenever you want to change your product name.",
"type": [
"string",
"null"
],
"format": "uuid"
},
"language": {
"description": "The installer languages to build. See <https://docs.microsoft.com/en-us/windows/win32/msi/localizing-the-error-and-actiontext-tables>.",
"default": "en-US",
Expand Down
1 change: 1 addition & 0 deletions crates/tauri-cli/src/helpers/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ pub type ConfigHandle = Arc<Mutex<Option<ConfigMetadata>>>;

pub fn wix_settings(config: WixConfig) -> tauri_bundler::WixSettings {
tauri_bundler::WixSettings {
upgrade_code: config.upgrade_code,
language: tauri_bundler::WixLanguage(match config.language {
WixLanguage::One(lang) => vec![(lang, Default::default())],
WixLanguage::List(languages) => languages
Expand Down
58 changes: 58 additions & 0 deletions crates/tauri-cli/src/inspect.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
// Copyright 2019-2024 Tauri Programme within The Commons Conservancy
// SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT

use anyhow::Result;
use clap::{Parser, Subcommand};

use crate::interface::{AppInterface, AppSettings, Interface};

#[derive(Debug, Parser)]
#[clap(about = "Manage or create permissions for your app or plugin")]
pub struct Cli {
#[clap(subcommand)]
command: Commands,
}

#[derive(Subcommand, Debug)]
enum Commands {
/// Print the default Upgrade Code used by MSI installer derived from productName.
WixUpgradeCode,
}

pub fn command(cli: Cli) -> Result<()> {
match cli.command {
Commands::WixUpgradeCode => wix_upgrade_code(),
}
}

// NOTE: if this is ever changed, make sure to also update Wix upgrade code generation in tauri-bundler
fn wix_upgrade_code() -> Result<()> {
crate::helpers::app_paths::resolve();

let target = tauri_utils::platform::Target::Windows;
let config = crate::helpers::config::get(target, None)?;

let interface = AppInterface::new(config.lock().unwrap().as_ref().unwrap(), None)?;

let product_name = interface.app_settings().get_package_settings().product_name;

let upgrade_code = uuid::Uuid::new_v5(
&uuid::Uuid::NAMESPACE_DNS,
format!("{product_name}.exe.app.x64").as_bytes(),
)
.to_string();

log::info!("Default WiX Upgrade Code, derived from {product_name}: {upgrade_code}");
if let Some(code) = config.lock().unwrap().as_ref().and_then(|c| {
c.bundle
.windows
.wix
.as_ref()
.and_then(|wix| wix.upgrade_code)
}) {
log::info!("Application Upgrade Code override: {code}");
}

Ok(())
}
3 changes: 3 additions & 0 deletions crates/tauri-cli/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ mod helpers;
mod icon;
mod info;
mod init;
mod inspect;
mod interface;
mod migrate;
mod mobile;
Expand Down Expand Up @@ -151,6 +152,7 @@ enum Commands {
Completions(completions::Options),
Permission(acl::permission::Cli),
Capability(acl::capability::Cli),
Inspect(inspect::Cli),
}

fn format_error<I: CommandFactory>(err: clap::Error) -> clap::Error {
Expand Down Expand Up @@ -268,6 +270,7 @@ where
#[cfg(target_os = "macos")]
Commands::Ios(c) => mobile::ios::command(c, cli.verbose)?,
Commands::Migrate => migrate::command()?,
Commands::Inspect(cli) => inspect::command(cli)?,
}

Ok(())
Expand Down
8 changes: 8 additions & 0 deletions crates/tauri-schema-generator/schemas/config.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -2170,6 +2170,14 @@
"description": "Configuration for the MSI bundle using WiX.\n\n See more: <https://tauri.app/v1/api/config#wixconfig>",
"type": "object",
"properties": {
"upgradeCode": {
"description": "A GUID upgrade code for MSI installer. This code **_must stay the same across all of your updates_**,\n otherwise, Windows will treat your update as a different app and your users will have duplicate versions of your app.\n\n By default, tauri generates this code by generating a Uuid v5 using the string `<productName>.exe.app.x64` in the DNS namespace.\n You can use Tauri's CLI to generate and print this code for you, run `tauri inspect wix-upgrade-code`.\n\n It is recommended that you set this value in your tauri config file to avoid accidental changes in your upgrade code\n whenever you want to change your product name.",
"type": [
"string",
"null"
],
"format": "uuid"
},
"language": {
"description": "The installer languages to build. See <https://docs.microsoft.com/en-us/windows/win32/msi/localizing-the-error-and-actiontext-tables>.",
"default": "en-US",
Expand Down
3 changes: 2 additions & 1 deletion crates/tauri-utils/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ html5ever = "0.26"
kuchiki = { package = "kuchikiki", version = "0.8" }
proc-macro2 = { version = "1", optional = true }
quote = { version = "1", optional = true }
schemars = { version = "0.8.18", features = ["url"], optional = true }
schemars = { version = "0.8.18", features = ["url", "uuid1"], optional = true }
serde_with = "3"
aes-gcm = { version = "0.10", optional = true }
getrandom = { version = "0.2", optional = true, features = ["std"] }
Expand All @@ -45,6 +45,7 @@ dunce = "1"
log = "0.4.21"
cargo_metadata = { version = "0.18", optional = true }
serde-untagged = "0.1"
uuid = { version = "1", features = ["serde"] }

[target."cfg(target_os = \"macos\")".dependencies]
swift-rs = { version = "1.0.7", optional = true, features = ["build"] }
Expand Down
10 changes: 10 additions & 0 deletions crates/tauri-utils/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -658,6 +658,16 @@ impl Default for WixLanguage {
#[cfg_attr(feature = "schema", derive(JsonSchema))]
#[serde(rename_all = "camelCase", deny_unknown_fields)]
pub struct WixConfig {
/// A GUID upgrade code for MSI installer. This code **_must stay the same across all of your updates_**,
/// otherwise, Windows will treat your update as a different app and your users will have duplicate versions of your app.
///
/// By default, tauri generates this code by generating a Uuid v5 using the string `<productName>.exe.app.x64` in the DNS namespace.
/// You can use Tauri's CLI to generate and print this code for you, run `tauri inspect wix-upgrade-code`.
///
/// It is recommended that you set this value in your tauri config file to avoid accidental changes in your upgrade code
/// whenever you want to change your product name.
#[serde(alias = "upgrade-code")]
pub upgrade_code: Option<uuid::Uuid>,
/// The installer languages to build. See <https://docs.microsoft.com/en-us/windows/win32/msi/localizing-the-error-and-actiontext-tables>.
#[serde(default)]
pub language: WixLanguage,
Expand Down

0 comments on commit f57a729

Please sign in to comment.