Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat!(core): add bundle createUpdaterArtifacts configuration #9883

Merged
merged 34 commits into from
Jul 1, 2024
Merged
Show file tree
Hide file tree
Changes from 31 commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
2eda9bc
Add updater field
Legend-Master May 26, 2024
0a3ba62
Don't sign updaters when updater field is false
Legend-Master May 26, 2024
18f580f
Clippy
Legend-Master May 26, 2024
9bf24c8
Add updater to bundle migration
Legend-Master May 26, 2024
eff1208
Format
Legend-Master May 26, 2024
908fd9c
Add updater config to api example
Legend-Master May 26, 2024
ae72665
No warning if update is not enabled
Legend-Master May 26, 2024
d133783
Build
Legend-Master May 26, 2024
c2d9681
Add change file
Legend-Master May 26, 2024
eafd3d1
Merge remote-tracking branch 'upstream/dev' into bundle-updater-field
Legend-Master May 26, 2024
67d9942
We don't generate updater for dmg package
Legend-Master May 26, 2024
c8fd8fd
Warning only for v1 compatible
Legend-Master May 27, 2024
25b432c
clean up
Legend-Master May 27, 2024
cb5094f
More clean up
Legend-Master May 27, 2024
c711f39
little bit more
Legend-Master May 27, 2024
c74bc58
Apply suggestions from code review
Legend-Master May 28, 2024
e143c87
Revert license header change
Legend-Master May 28, 2024
ee0ee6b
Remove option around pubkey and msi args
Legend-Master May 28, 2024
60eac52
More migration tests
Legend-Master May 28, 2024
491bfd0
Refactor private_key getter
Legend-Master May 28, 2024
475f2db
Only generate signature for updater for v1 compat
Legend-Master May 28, 2024
e665f5c
Format
Legend-Master May 28, 2024
b937690
Use map_err instead of anyhow context
Legend-Master May 28, 2024
adc2f35
Don't generate updater for api example
Legend-Master May 28, 2024
5f3c2b4
Fix misaligned comment
Legend-Master May 28, 2024
3268098
Rename `updater` to `createUpdaterArtifacts`
Legend-Master May 28, 2024
b0b8f85
Merge branch 'dev' into bundle-updater-field
Legend-Master May 29, 2024
1d55f79
Merge branch 'dev' into bundle-updater-field
Legend-Master May 29, 2024
d9dd062
Revert changes in helloworld example
Legend-Master May 29, 2024
2c9b492
Merge remote-tracking branch 'upstream/dev' into bundle-updater-field
Legend-Master May 30, 2024
ef16c6b
Add warning for v1 compatible
Legend-Master May 30, 2024
b6bf36e
Merge remote-tracking branch 'upstream/dev' into bundle-updater-field
Legend-Master Jun 29, 2024
1670998
Update .changes/separate-updater-field.md
Legend-Master Jun 29, 2024
1076251
update error messages [skip ci]
lucasfernog Jul 1, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .changes/separate-updater-field.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
"tauri-utils": patch:breaking
"tauri-bundler": patch:breaking
"tauri-cli": patch:breaking
"@tauri-apps/cli": patch:breaking
---

Move updater target from `bundle > targets` to a separate field `bundle > updater`
Legend-Master marked this conversation as resolved.
Show resolved Hide resolved
38 changes: 35 additions & 3 deletions core/tauri-config-schema/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@
"android": {
"minSdkVersion": 24
},
"createUpdaterArtifacts": false,
"iOS": {},
"icon": [],
"linux": {
Expand Down Expand Up @@ -1517,14 +1518,23 @@
"type": "boolean"
},
"targets": {
"description": "The bundle targets, currently supports [\"deb\", \"rpm\", \"appimage\", \"nsis\", \"msi\", \"app\", \"dmg\", \"updater\"] or \"all\".",
"description": "The bundle targets, currently supports [\"deb\", \"rpm\", \"appimage\", \"nsis\", \"msi\", \"app\", \"dmg\"] or \"all\".",
"default": "all",
"allOf": [
{
"$ref": "#/definitions/BundleTarget"
}
]
},
"createUpdaterArtifacts": {
"description": "Produce updaters and their signatures or not",
"default": false,
"allOf": [
{
"$ref": "#/definitions/Updater"
}
]
},
"publisher": {
"description": "The application's publisher. Defaults to the second element in the identifier string. Currently maps to the Manufacturer property of the Windows Installer.",
"type": [
Expand Down Expand Up @@ -1784,12 +1794,34 @@
"enum": [
"dmg"
]
}
]
},
"Updater": {
"description": "Updater type",
"anyOf": [
{
"description": "Generates lagacy zipped v1 compatible updaters",
"allOf": [
{
"$ref": "#/definitions/V1Compatible"
}
]
},
{
"description": "The Tauri updater bundle.",
"description": "Produce updaters and their signatures or not",
"type": "boolean"
}
]
},
"V1Compatible": {
"description": "Generates lagacy zipped v1 compatible updaters",
"oneOf": [
{
"description": "Generates lagacy zipped v1 compatible updaters",
"type": "string",
"enum": [
"updater"
"v1Compatible"
]
}
]
Expand Down
40 changes: 34 additions & 6 deletions core/tauri-utils/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,8 +115,6 @@ pub enum BundleType {
App,
/// The Apple Disk Image bundle (.dmg).
Dmg,
/// The Tauri updater bundle.
Updater,
}

impl BundleType {
Expand All @@ -130,7 +128,6 @@ impl BundleType {
BundleType::Nsis,
BundleType::App,
BundleType::Dmg,
BundleType::Updater,
]
}
}
Expand All @@ -148,7 +145,6 @@ impl Display for BundleType {
Self::Nsis => "nsis",
Self::App => "app",
Self::Dmg => "dmg",
Self::Updater => "updater",
}
)
}
Expand Down Expand Up @@ -177,7 +173,6 @@ impl<'de> Deserialize<'de> for BundleType {
"nsis" => Ok(Self::Nsis),
"app" => Ok(Self::App),
"dmg" => Ok(Self::Dmg),
"updater" => Ok(Self::Updater),
_ => Err(DeError::custom(format!("unknown bundle target '{s}'"))),
}
}
Expand Down Expand Up @@ -1037,6 +1032,33 @@ impl BundleResources {
}
}

/// Updater type
#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]
#[cfg_attr(feature = "schema", derive(JsonSchema))]
#[serde(rename_all = "camelCase", deny_unknown_fields, untagged)]
pub enum Updater {
/// Generates lagacy zipped v1 compatible updaters
String(V1Compatible),
/// Produce updaters and their signatures or not
// Can't use untagged on enum field here: https://github.com/GREsau/schemars/issues/222
Bool(bool),
}

impl Default for Updater {
fn default() -> Self {
Self::Bool(false)
Legend-Master marked this conversation as resolved.
Show resolved Hide resolved
}
}

/// Generates lagacy zipped v1 compatible updaters
#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]
#[cfg_attr(feature = "schema", derive(JsonSchema))]
#[serde(rename_all = "camelCase", deny_unknown_fields)]
pub enum V1Compatible {
/// Generates lagacy zipped v1 compatible updaters
V1Compatible,
}

/// Configuration for tauri-bundler.
///
/// See more: <https://tauri.app/v1/api/config#bundleconfig>
Expand All @@ -1048,9 +1070,12 @@ pub struct BundleConfig {
/// Whether Tauri should bundle your application or just output the executable.
#[serde(default)]
pub active: bool,
/// The bundle targets, currently supports ["deb", "rpm", "appimage", "nsis", "msi", "app", "dmg", "updater"] or "all".
/// The bundle targets, currently supports ["deb", "rpm", "appimage", "nsis", "msi", "app", "dmg"] or "all".
#[serde(default)]
pub targets: BundleTarget,
#[serde(default)]
/// Produce updaters and their signatures or not
pub create_updater_artifacts: Updater,
/// The application's publisher. Defaults to the second element in the identifier string.
/// Currently maps to the Manufacturer property of the Windows Installer.
pub publisher: Option<String>,
Expand Down Expand Up @@ -2419,6 +2444,7 @@ mod build {
let icon = vec_lit(&self.icon, str_lit);
let active = self.active;
let targets = quote!(Default::default());
let create_updater_artifacts = quote!(Default::default());
let resources = quote!(None);
let copyright = quote!(None);
let category = quote!(None);
Expand All @@ -2441,6 +2467,7 @@ mod build {
publisher,
icon,
targets,
create_updater_artifacts,
resources,
copyright,
category,
Expand Down Expand Up @@ -2755,6 +2782,7 @@ mod test {
let bundle = BundleConfig {
active: false,
targets: Default::default(),
create_updater_artifacts: Default::default(),
publisher: None,
icon: Vec::new(),
resources: None,
Expand Down
121 changes: 66 additions & 55 deletions tooling/bundler/src/bundle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,16 +42,14 @@ pub struct Bundle {

/// Bundles the project.
/// Returns the list of paths where the bundles can be found.
pub fn bundle_project(settings: Settings) -> crate::Result<Vec<Bundle>> {
pub fn bundle_project(settings: &Settings) -> crate::Result<Vec<Bundle>> {
let mut package_types = settings.package_types()?;
if package_types.is_empty() {
return Ok(Vec::new());
}

package_types.sort_by_key(|a| a.priority());

let mut bundles: Vec<Bundle> = Vec::new();

let target_os = settings
.target()
.split('-')
Expand All @@ -68,7 +66,7 @@ pub fn bundle_project(settings: Settings) -> crate::Result<Vec<Bundle>> {
if settings.can_sign() {
for bin in settings.binaries() {
let bin_path = settings.binary_path(bin);
windows::sign::try_sign(&bin_path, &settings)?;
windows::sign::try_sign(&bin_path, settings)?;
}

// Sign the sidecar binaries
Expand All @@ -89,14 +87,15 @@ pub fn bundle_project(settings: Settings) -> crate::Result<Vec<Bundle>> {
continue;
}

windows::sign::try_sign(&path, &settings)?;
windows::sign::try_sign(&path, settings)?;
}
} else {
#[cfg(not(target_os = "windows"))]
log::warn!("Signing, by default, is only supported on Windows hosts, but you can specify a custom signing command in `bundler > windows > sign_command`, for now, skipping signing the installer...");
}
}

let mut bundles = Vec::<Bundle>::new();
for package_type in &package_types {
// bundle was already built! e.g. DMG already built .app
if bundles.iter().any(|b| b.package_type == *package_type) {
Expand All @@ -105,13 +104,13 @@ pub fn bundle_project(settings: Settings) -> crate::Result<Vec<Bundle>> {

let bundle_paths = match package_type {
#[cfg(target_os = "macos")]
PackageType::MacOsBundle => macos::app::bundle_project(&settings)?,
PackageType::MacOsBundle => macos::app::bundle_project(settings)?,
#[cfg(target_os = "macos")]
PackageType::IosBundle => macos::ios::bundle_project(&settings)?,
PackageType::IosBundle => macos::ios::bundle_project(settings)?,
// dmg is dependent of MacOsBundle, we send our bundles to prevent rebuilding
#[cfg(target_os = "macos")]
PackageType::Dmg => {
let bundled = macos::dmg::bundle_project(&settings, &bundles)?;
let bundled = macos::dmg::bundle_project(settings, &bundles)?;
if !bundled.app.is_empty() {
bundles.push(Bundle {
package_type: PackageType::MacOsBundle,
Expand All @@ -122,33 +121,15 @@ pub fn bundle_project(settings: Settings) -> crate::Result<Vec<Bundle>> {
}

#[cfg(target_os = "windows")]
PackageType::WindowsMsi => windows::msi::bundle_project(&settings, false)?,
PackageType::Nsis => windows::nsis::bundle_project(&settings, false)?,
PackageType::WindowsMsi => windows::msi::bundle_project(settings, false)?,
PackageType::Nsis => windows::nsis::bundle_project(settings, false)?,

#[cfg(target_os = "linux")]
PackageType::Deb => linux::debian::bundle_project(&settings)?,
PackageType::Deb => linux::debian::bundle_project(settings)?,
#[cfg(target_os = "linux")]
PackageType::Rpm => linux::rpm::bundle_project(&settings)?,
PackageType::Rpm => linux::rpm::bundle_project(settings)?,
#[cfg(target_os = "linux")]
PackageType::AppImage => linux::appimage::bundle_project(&settings)?,

// updater is dependent of multiple bundle, we send our bundles to prevent rebuilding
PackageType::Updater => {
if !package_types.iter().any(|p| {
matches!(
p,
PackageType::AppImage
| PackageType::MacOsBundle
| PackageType::Dmg
| PackageType::Nsis
| PackageType::WindowsMsi
)
}) {
log::warn!("The updater bundle target exists but couldn't find any updater-enabled target, so the updater artifacts won't be generated. Please add one of these targets as well: app, appimage, msi, nsis");
continue;
}
updater_bundle::bundle_project(&settings, &bundles)?
}
PackageType::AppImage => linux::appimage::bundle_project(settings)?,
_ => {
log::warn!("ignoring {}", package_type.short_name());
continue;
Expand All @@ -161,6 +142,33 @@ pub fn bundle_project(settings: Settings) -> crate::Result<Vec<Bundle>> {
});
}

if let Some(updater) = settings.updater() {
if package_types.iter().any(|package_type| {
if updater.v1_compatible {
matches!(
package_type,
PackageType::AppImage
| PackageType::MacOsBundle
| PackageType::Nsis
| PackageType::WindowsMsi
)
} else {
matches!(package_type, PackageType::MacOsBundle)
}
}) {
let updater_paths = updater_bundle::bundle_project(settings, &bundles)?;
bundles.push(Bundle {
package_type: PackageType::Updater,
bundle_paths: updater_paths,
});
} else if updater.v1_compatible {
log::warn!("The updater bundle target exists but couldn't find any updater-enabled target, so the updater artifacts won't be generated. Please add one of these targets as well: app, appimage, msi, nsis");
}
if updater.v1_compatible {
log::warn!("Legacy v1 compatible updater is deprecated and will be removed in v3, change bundle > createUpdaterArtifacts to true when your users are updated to the version with v2 updater plugin");
}
}

#[cfg(target_os = "macos")]
{
// Clean up .app if only building dmg or updater
Expand Down Expand Up @@ -188,34 +196,37 @@ pub fn bundle_project(settings: Settings) -> crate::Result<Vec<Bundle>> {
}
}

if !bundles.is_empty() {
let bundles_wo_updater = bundles
.iter()
.filter(|b| b.package_type != PackageType::Updater)
.collect::<Vec<_>>();
let pluralised = if bundles_wo_updater.len() == 1 {
"bundle"
} else {
"bundles"
};
if bundles.is_empty() {
return Err(anyhow::anyhow!("No bundles were built").into());
}

let mut printable_paths = String::new();
for bundle in &bundles {
for path in &bundle.bundle_paths {
let mut note = "";
if bundle.package_type == crate::PackageType::Updater {
note = " (updater)";
}
writeln!(printable_paths, " {}{}", display_path(path), note).unwrap();
}
let bundles_wo_updater = bundles
.iter()
.filter(|b| b.package_type != PackageType::Updater)
.collect::<Vec<_>>();
let finished_bundles = bundles_wo_updater.len();
let pluralised = if finished_bundles == 1 {
"bundle"
} else {
"bundles"
};

let mut printable_paths = String::new();
for bundle in &bundles {
for path in &bundle.bundle_paths {
let note = if bundle.package_type == crate::PackageType::Updater {
" (updater)"
} else {
""
};
let path_display = display_path(path);
writeln!(printable_paths, " {path_display}{note}").unwrap();
}
}

log::info!(action = "Finished"; "{} {} at:\n{}", bundles_wo_updater.len(), pluralised, printable_paths);
log::info!(action = "Finished"; "{finished_bundles} {pluralised} at:\n{printable_paths}");

Ok(bundles)
} else {
Err(anyhow::anyhow!("No bundles were built").into())
}
Ok(bundles)
}

/// Check to see if there are icons in the settings struct
Expand Down
Loading
Loading