Fix: Updater funktioniert jetzt auch bei lokalen Builds [appimage]
All checks were successful
Build AppImage / build (push) Successful in 8m51s
All checks were successful
Build AppImage / build (push) Successful in 8m51s
Dev-Check entfernt der Updates bei lokalen Builds blockiert hat. Jede gültige Remote-Version wird bei dev/dev-local als neuer erkannt. HTTP/Netzwerk-Fehler werden graceful behandelt statt zu crashen. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
0a447591da
commit
9be09897dd
1 changed files with 62 additions and 23 deletions
|
|
@ -103,7 +103,7 @@ const PACKAGE_BASE_URL: &str =
|
||||||
"https://git.data-it-solution.de/api/packages/data/generic/claude-desktop/latest/";
|
"https://git.data-it-solution.de/api/packages/data/generic/claude-desktop/latest/";
|
||||||
|
|
||||||
/// Version der laufenden App. Wird von der CI als APP_VERSION zur Build-Zeit gesetzt.
|
/// Version der laufenden App. Wird von der CI als APP_VERSION zur Build-Zeit gesetzt.
|
||||||
/// Lokaler Build ohne Env-Var → "dev" → Update-Check wird übersprungen.
|
/// Lokaler Build ohne Env-Var → "dev" → Update wird trotzdem geprüft (jede Remote-Version gilt als neuer).
|
||||||
const CURRENT_VERSION: &str = match option_env!("APP_VERSION") {
|
const CURRENT_VERSION: &str = match option_env!("APP_VERSION") {
|
||||||
Some(v) => v,
|
Some(v) => v,
|
||||||
None => "dev",
|
None => "dev",
|
||||||
|
|
@ -171,34 +171,41 @@ fn authed_get(client: &reqwest::Client, url: &str) -> reqwest::RequestBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Prüft ob ein Update verfügbar ist.
|
/// Prüft ob ein Update verfügbar ist.
|
||||||
/// Lokale Dev-Builds ohne APP_VERSION-Env geben sofort available=false zurück.
|
/// Auch Dev-Builds prüfen — jede Remote-Version gilt dann als neuer.
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
pub async fn check_for_update() -> Result<UpdateStatus, String> {
|
pub async fn check_for_update() -> Result<UpdateStatus, String> {
|
||||||
// Dev-Build → kein Update-Check
|
let client = reqwest::Client::new();
|
||||||
if CURRENT_VERSION == "dev" {
|
let response = match authed_get(&client, UPDATE_JSON_URL).send().await {
|
||||||
|
Ok(r) => r,
|
||||||
|
Err(e) => {
|
||||||
|
// Netzwerkfehler → kein Crash, einfach "kein Update gefunden"
|
||||||
return Ok(UpdateStatus {
|
return Ok(UpdateStatus {
|
||||||
available: false,
|
available: false,
|
||||||
current_version: CURRENT_VERSION.to_string(),
|
current_version: CURRENT_VERSION.to_string(),
|
||||||
latest_version: None,
|
latest_version: None,
|
||||||
release_notes: Some("Entwicklungs-Build — Updates deaktiviert.".to_string()),
|
release_notes: Some(format!("Update-Check fehlgeschlagen (Netzwerk): {}", e)),
|
||||||
download_url: None,
|
download_url: None,
|
||||||
download_size: None,
|
download_size: None,
|
||||||
sha256: None,
|
sha256: None,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
};
|
||||||
let client = reqwest::Client::new();
|
|
||||||
let response = authed_get(&client, UPDATE_JSON_URL)
|
|
||||||
.send()
|
|
||||||
.await
|
|
||||||
.map_err(|e| format!("Netzwerkfehler beim Update-Check: {}", e))?;
|
|
||||||
|
|
||||||
if !response.status().is_success() {
|
if !response.status().is_success() {
|
||||||
return Err(format!(
|
// 401/403 ohne Token oder mit falschem Token → kein Crash, nur Hinweis
|
||||||
"Manifest-Abruf fehlgeschlagen ({}). Token konfiguriert: {}",
|
return Ok(UpdateStatus {
|
||||||
|
available: false,
|
||||||
|
current_version: CURRENT_VERSION.to_string(),
|
||||||
|
latest_version: None,
|
||||||
|
release_notes: Some(format!(
|
||||||
|
"Update-Check fehlgeschlagen (HTTP {}). Token konfiguriert: {}",
|
||||||
response.status(),
|
response.status(),
|
||||||
UPDATE_TOKEN.is_some()
|
UPDATE_TOKEN.is_some()
|
||||||
));
|
)),
|
||||||
|
download_url: None,
|
||||||
|
download_size: None,
|
||||||
|
sha256: None,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
let manifest: UpdateManifest = response
|
let manifest: UpdateManifest = response
|
||||||
|
|
@ -448,13 +455,26 @@ pub fn get_current_version() -> String {
|
||||||
CURRENT_VERSION.to_string()
|
CURRENT_VERSION.to_string()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Prüft ob eine Version ein gültiges Zeitstempel-Format hat (nur Ziffern und Bindestriche).
|
||||||
|
/// Beispiel: "20260420-1300" → true, "dev" → false, "dev-local" → false
|
||||||
|
fn is_timestamp_version(v: &str) -> bool {
|
||||||
|
!v.is_empty() && v.chars().all(|c| c.is_ascii_digit() || c == '-')
|
||||||
|
}
|
||||||
|
|
||||||
/// String-Vergleich für `YYYYMMDD-HHMM`-Versionen.
|
/// String-Vergleich für `YYYYMMDD-HHMM`-Versionen.
|
||||||
/// Lexikographisch > ist bei Zeitstempel-Format korrekt.
|
/// Lexikographisch > ist bei Zeitstempel-Format korrekt.
|
||||||
/// "dev" ist immer "nicht neuer".
|
/// Wenn die lokale Version kein gültiger Zeitstempel ist (z.B. "dev", "dev-local"),
|
||||||
|
/// gilt jede Remote-Version als neuer → Update immer anbieten.
|
||||||
fn is_newer(candidate: &str, current: &str) -> bool {
|
fn is_newer(candidate: &str, current: &str) -> bool {
|
||||||
if candidate == "dev" || current == "dev" {
|
// Remote-Version muss ein gültiger Zeitstempel sein
|
||||||
|
if !is_timestamp_version(candidate) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
// Lokale Version kein Zeitstempel → jede gültige Remote-Version ist neuer
|
||||||
|
if !is_timestamp_version(current) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// Beide gültig → lexikographischer Vergleich
|
||||||
candidate > current
|
candidate > current
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -471,9 +491,28 @@ mod tests {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_is_newer_dev_always_false() {
|
fn test_is_newer_dev_local_immer_update() {
|
||||||
|
// Lokale Version "dev" oder "dev-local" → jede gültige Remote-Version ist neuer
|
||||||
|
assert!(is_newer("20260420-1200", "dev"));
|
||||||
|
assert!(is_newer("20260420-1200", "dev-local"));
|
||||||
|
assert!(is_newer("20260101-0000", "dev"));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_is_newer_remote_dev_nie() {
|
||||||
|
// Remote-Version "dev" → niemals als neuer behandeln
|
||||||
assert!(!is_newer("dev", "20260420-1200"));
|
assert!(!is_newer("dev", "20260420-1200"));
|
||||||
assert!(!is_newer("20260420-1200", "dev"));
|
|
||||||
assert!(!is_newer("dev", "dev"));
|
assert!(!is_newer("dev", "dev"));
|
||||||
|
assert!(!is_newer("dev-local", "dev"));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_is_timestamp_version() {
|
||||||
|
assert!(is_timestamp_version("20260420-1300"));
|
||||||
|
assert!(is_timestamp_version("20260101-0000"));
|
||||||
|
assert!(!is_timestamp_version("dev"));
|
||||||
|
assert!(!is_timestamp_version("dev-local"));
|
||||||
|
assert!(!is_timestamp_version("v1.0.0"));
|
||||||
|
assert!(!is_timestamp_version(""));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue