Skip to content

Commit 20ff1f4

Browse files
feat(bundler): Add support for numeric-only build numbers in msi version (#6096)
Co-authored-by: Lucas Nogueira <lucas@tauri.studio>
1 parent fc193a5 commit 20ff1f4

File tree

3 files changed

+53
-26
lines changed

3 files changed

+53
-26
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'tauri-bundler': 'minor'
3+
---
4+
5+
Added support for pre-release identifiers and build numbers for the `.msi` bundle target. Only one of each can be used and it must be numeric only. The version must still be semver compatible according to https://semver.org/.

tooling/bundler/src/bundle/windows/msi/wix.rs

Lines changed: 48 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,11 @@ use crate::bundle::{
88
path_utils::{copy_file, FileOpts},
99
settings::Settings,
1010
windows::util::{
11-
download, download_and_verify, extract_zip, try_sign, validate_version, HashAlgorithm,
12-
WEBVIEW2_BOOTSTRAPPER_URL, WEBVIEW2_X64_INSTALLER_GUID, WEBVIEW2_X86_INSTALLER_GUID,
11+
download, download_and_verify, extract_zip, try_sign, HashAlgorithm, WEBVIEW2_BOOTSTRAPPER_URL,
12+
WEBVIEW2_X64_INSTALLER_GUID, WEBVIEW2_X86_INSTALLER_GUID,
1313
},
1414
};
15-
use anyhow::Context;
15+
use anyhow::{bail, Context};
1616
use handlebars::{to_json, Handlebars};
1717
use log::info;
1818
use regex::Regex;
@@ -177,6 +177,7 @@ fn copy_icon(settings: &Settings, filename: &str, path: &Path) -> crate::Result<
177177
fn app_installer_output_path(
178178
settings: &Settings,
179179
language: &str,
180+
version: &str,
180181
updater: bool,
181182
) -> crate::Result<PathBuf> {
182183
let arch = match settings.binary_arch() {
@@ -193,7 +194,7 @@ fn app_installer_output_path(
193194
let package_base_name = format!(
194195
"{}_{}_{}_{}",
195196
settings.main_binary_name().replace(".exe", ""),
196-
settings.version_string(),
197+
version,
197198
arch,
198199
language,
199200
);
@@ -243,6 +244,46 @@ fn clear_env_for_wix(cmd: &mut Command) {
243244
}
244245
}
245246

247+
// WiX requires versions to be numeric only in a `major.minor.patch.build` format
248+
pub fn convert_version(version_str: &str) -> anyhow::Result<String> {
249+
let version = semver::Version::parse(version_str).context("invalid app version")?;
250+
if version.major > 255 {
251+
bail!("app version major number cannot be greater than 255");
252+
}
253+
if version.minor > 255 {
254+
bail!("app version minor number cannot be greater than 255");
255+
}
256+
if version.patch > 65535 {
257+
bail!("app version patch number cannot be greater than 65535");
258+
}
259+
260+
if !version.build.is_empty() {
261+
let build = version.build.parse::<u64>();
262+
if build.map(|b| b <= 65535).unwrap_or_default() {
263+
return Ok(format!(
264+
"{}.{}.{}.{}",
265+
version.major, version.minor, version.patch, version.build
266+
));
267+
} else {
268+
bail!("optional build metadata in app version must be numeric-only and cannot be greater than 65535 for msi target");
269+
}
270+
}
271+
272+
if !version.pre.is_empty() {
273+
let pre = version.pre.parse::<u64>();
274+
if pre.is_ok() && pre.unwrap() <= 65535 {
275+
return Ok(format!(
276+
"{}.{}.{}.{}",
277+
version.major, version.minor, version.patch, version.pre
278+
));
279+
} else {
280+
bail!("optional pre-release identifier in app version must be numeric-only and cannot be greater than 65535 for msi target");
281+
}
282+
}
283+
284+
Ok(version_str.to_string())
285+
}
286+
246287
/// Runs the Candle.exe executable for Wix. Candle parses the wxs file and generates the code for building the installer.
247288
fn run_candle(
248289
settings: &Settings,
@@ -363,7 +404,7 @@ pub fn build_wix_app_installer(
363404
}
364405
};
365406

366-
validate_version(settings.version_string())?;
407+
let app_version = convert_version(settings.version_string())?;
367408

368409
// target only supports x64.
369410
info!("Target: {}", arch);
@@ -515,7 +556,7 @@ pub fn build_wix_app_installer(
515556
.unwrap_or_default();
516557

517558
data.insert("product_name", to_json(settings.product_name()));
518-
data.insert("version", to_json(settings.version_string()));
559+
data.insert("version", to_json(&app_version));
519560
let bundle_id = settings.bundle_identifier();
520561
let manufacturer = settings
521562
.publisher()
@@ -764,7 +805,7 @@ pub fn build_wix_app_installer(
764805
"*.wixobj".into(),
765806
];
766807
let msi_output_path = output_path.join("output.msi");
767-
let msi_path = app_installer_output_path(settings, &language, updater)?;
808+
let msi_path = app_installer_output_path(settings, &language, &app_version, updater)?;
768809
create_dir_all(msi_path.parent().unwrap())?;
769810

770811
info!(action = "Running"; "light to produce {}", msi_path.display());

tooling/bundler/src/bundle/windows/util.rs

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ use std::{
88
path::{Path, PathBuf},
99
};
1010

11-
use anyhow::{bail, Context};
1211
use log::info;
1312
use sha2::Digest;
1413
use zip::ZipArchive;
@@ -68,24 +67,6 @@ fn verify(data: &Vec<u8>, hash: &str, mut hasher: impl Digest) -> crate::Result<
6867
}
6968
}
7069

71-
pub fn validate_version(version: &str) -> anyhow::Result<()> {
72-
let version = semver::Version::parse(version).context("invalid app version")?;
73-
if version.major > 255 {
74-
bail!("app version major number cannot be greater than 255");
75-
}
76-
if version.minor > 255 {
77-
bail!("app version minor number cannot be greater than 255");
78-
}
79-
if version.patch > 65535 {
80-
bail!("app version patch number cannot be greater than 65535");
81-
}
82-
if !(version.pre.is_empty() && version.build.is_empty()) {
83-
bail!("app version cannot have build metadata or pre-release identifier");
84-
}
85-
86-
Ok(())
87-
}
88-
8970
pub fn try_sign(file_path: &PathBuf, settings: &Settings) -> crate::Result<()> {
9071
if let Some(certificate_thumbprint) = settings.windows().certificate_thumbprint.as_ref() {
9172
info!(action = "Signing"; "{}", file_path.display());

0 commit comments

Comments
 (0)