feat(updater): gate auto-updater behind Cargo feature updater
Makes tauri-plugin-updater and tauri-plugin-process optional dependencies enabled by a default-on `updater` Cargo feature. Sandboxed packaging targets (Flatpak, Snap) will build with `--no-default-features` to exclude the plugins entirely, satisfying store policies that prohibit competing auto-updaters. Changes: - Cargo.toml: add `updater` feature; plugins are now optional deps - lib.rs: gate plugin registration on the feature - updates/mod.rs: is_auto_update_eligible() returns false when the feature is off (catch-all for unusual build configs) - capabilities/default.json: remove updater/process permissions - build.rs: emit capabilities/auto-updater.json only when the feature is enabled; remove it otherwise. The file is gitignored since it is fully build-driven. cc
This commit is contained in:
6 files changed
+62
-11
No files matched your search
@@ -31,6 +31,8 @@ snapcraft-*.txt
|
|||||||
|
|
||||||
# Tauri
|
# Tauri
|
||||||
src-tauri/target/
|
src-tauri/target/
|
||||||
|
# Generated by build.rs based on `updater` Cargo feature
|
||||||
|
src-tauri/capabilities/auto-updater.json
|
||||||
|
|
||||||
# Svelte
|
# Svelte
|
||||||
.svelte-kit/
|
.svelte-kit/
|
||||||
|
|||||||
@@ -16,6 +16,13 @@ path = "src/main.rs"
|
|||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
tauri-build = { version = "2", features = [] }
|
tauri-build = { version = "2", features = [] }
|
||||||
|
|
||||||
|
[features]
|
||||||
|
default = ["updater"]
|
||||||
|
# Enables the in-app auto-updater (tauri-plugin-updater + tauri-plugin-process).
|
||||||
|
# Disabled for sandboxed packaging targets (Flatpak, Snap) which have their own
|
||||||
|
# update channels and whose store policies prohibit competing updaters.
|
||||||
|
updater = ["dep:tauri-plugin-updater", "dep:tauri-plugin-process"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
# QBZ Crates (extracted core functionality)
|
# QBZ Crates (extracted core functionality)
|
||||||
qbz-models = { path = "../crates/qbz-models" }
|
qbz-models = { path = "../crates/qbz-models" }
|
||||||
@@ -39,8 +46,8 @@ tauri-plugin-opener = "2"
|
|||||||
tauri-plugin-os = "2"
|
tauri-plugin-os = "2"
|
||||||
tauri-plugin-single-instance = { version = "2", features = ["deep-link"] }
|
tauri-plugin-single-instance = { version = "2", features = ["deep-link"] }
|
||||||
tauri-plugin-deep-link = "2"
|
tauri-plugin-deep-link = "2"
|
||||||
tauri-plugin-updater = "2"
|
tauri-plugin-updater = { version = "2", optional = true }
|
||||||
tauri-plugin-process = "2"
|
tauri-plugin-process = { version = "2", optional = true }
|
||||||
|
|
||||||
# Serialization
|
# Serialization
|
||||||
serde = { version = "1", features = ["derive"] }
|
serde = { version = "1", features = ["derive"] }
|
||||||
|
|||||||
@@ -1,3 +1,35 @@
|
|||||||
|
use std::fs;
|
||||||
|
use std::path::Path;
|
||||||
|
|
||||||
|
/// Auto-updater capability, emitted to capabilities/ only when the `updater`
|
||||||
|
/// Cargo feature is active. Gitignored so Flatpak/Snap builds (which disable
|
||||||
|
/// the feature) never reference permissions for plugins that aren't linked.
|
||||||
|
const AUTO_UPDATER_CAPABILITY: &str = r#"{
|
||||||
|
"$schema": "../gen/schemas/desktop-schema.json",
|
||||||
|
"identifier": "auto-updater",
|
||||||
|
"description": "Permissions for the in-app auto-updater (macOS + Linux AppImage). Generated by build.rs when the `updater` Cargo feature is enabled.",
|
||||||
|
"windows": ["main", "miniplayer"],
|
||||||
|
"permissions": [
|
||||||
|
"updater:default",
|
||||||
|
"process:allow-restart"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
"#;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
let capability_path = Path::new("capabilities/auto-updater.json");
|
||||||
|
|
||||||
|
if cfg!(feature = "updater") {
|
||||||
|
if let Err(e) = fs::write(capability_path, AUTO_UPDATER_CAPABILITY) {
|
||||||
|
panic!("Failed to emit auto-updater capability: {e}");
|
||||||
|
}
|
||||||
|
} else if capability_path.exists() {
|
||||||
|
if let Err(e) = fs::remove_file(capability_path) {
|
||||||
|
panic!("Failed to remove stale auto-updater capability: {e}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("cargo:rerun-if-changed=build.rs");
|
||||||
|
|
||||||
tauri_build::build()
|
tauri_build::build()
|
||||||
}
|
}
|
||||||
@@ -36,8 +36,6 @@
|
|||||||
"os:default",
|
"os:default",
|
||||||
"dialog:default",
|
"dialog:default",
|
||||||
"clipboard-manager:default",
|
"clipboard-manager:default",
|
||||||
"clipboard-manager:allow-write-text",
|
"clipboard-manager:allow-write-text"
|
||||||
"updater:default",
|
|
||||||
"process:allow-restart"
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -729,7 +729,7 @@ pub fn run() {
|
|||||||
// Initialize per-user data paths (no user active yet until login)
|
// Initialize per-user data paths (no user active yet until login)
|
||||||
let user_data_paths = user_data::UserDataPaths::new();
|
let user_data_paths = user_data::UserDataPaths::new();
|
||||||
|
|
||||||
tauri::Builder::default()
|
let builder = tauri::Builder::default()
|
||||||
.plugin(tauri_plugin_single_instance::init(|app, args, _cwd| {
|
.plugin(tauri_plugin_single_instance::init(|app, args, _cwd| {
|
||||||
// Second instance launched — bring existing window to front
|
// Second instance launched — bring existing window to front
|
||||||
if let Some(window) = app.get_webview_window("main") {
|
if let Some(window) = app.get_webview_window("main") {
|
||||||
@@ -750,9 +750,14 @@ pub fn run() {
|
|||||||
.plugin(tauri_plugin_opener::init())
|
.plugin(tauri_plugin_opener::init())
|
||||||
.plugin(tauri_plugin_os::init())
|
.plugin(tauri_plugin_os::init())
|
||||||
.plugin(tauri_plugin_dialog::init())
|
.plugin(tauri_plugin_dialog::init())
|
||||||
.plugin(tauri_plugin_clipboard_manager::init())
|
.plugin(tauri_plugin_clipboard_manager::init());
|
||||||
|
|
||||||
|
#[cfg(feature = "updater")]
|
||||||
|
let builder = builder
|
||||||
.plugin(tauri_plugin_updater::Builder::new().build())
|
.plugin(tauri_plugin_updater::Builder::new().build())
|
||||||
.plugin(tauri_plugin_process::init())
|
.plugin(tauri_plugin_process::init());
|
||||||
|
|
||||||
|
builder
|
||||||
.manage(AppState::with_device_and_settings(
|
.manage(AppState::with_device_and_settings(
|
||||||
saved_device,
|
saved_device,
|
||||||
audio_settings,
|
audio_settings,
|
||||||
|
|||||||
@@ -661,13 +661,20 @@ pub async fn fetch_release_for_version(
|
|||||||
/// - Linux AppImage (detected via APPIMAGE env var)
|
/// - Linux AppImage (detected via APPIMAGE env var)
|
||||||
///
|
///
|
||||||
/// Not supported for Flatpak, Snap, DEB, RPM, AUR, Gentoo (they have their own update channels).
|
/// Not supported for Flatpak, Snap, DEB, RPM, AUR, Gentoo (they have their own update channels).
|
||||||
|
/// Also returns false unconditionally when the `updater` Cargo feature is disabled
|
||||||
|
/// (i.e., sandboxed Flatpak/Snap builds that don't link tauri-plugin-updater).
|
||||||
pub fn is_auto_update_eligible() -> bool {
|
pub fn is_auto_update_eligible() -> bool {
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(not(feature = "updater"))]
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(all(feature = "updater", target_os = "macos"))]
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(all(feature = "updater", target_os = "linux"))]
|
||||||
{
|
{
|
||||||
if crate::flatpak::is_flatpak() || crate::snap::is_snap() {
|
if crate::flatpak::is_flatpak() || crate::snap::is_snap() {
|
||||||
return false;
|
return false;
|
||||||
@@ -675,7 +682,7 @@ pub fn is_auto_update_eligible() -> bool {
|
|||||||
return env::var("APPIMAGE").is_ok();
|
return env::var("APPIMAGE").is_ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(any(target_os = "macos", target_os = "linux")))]
|
#[cfg(all(feature = "updater", not(any(target_os = "macos", target_os = "linux"))))]
|
||||||
{
|
{
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user