Compare commits

...

1 Commits

Author SHA1 Message Date
d2c1c2108a Fix update checker to use full semver comparison and correct platform filtering
Some checks failed
Build App / compute-version (push) Successful in 5s
Build App / build-macos (push) Successful in 2m20s
Build App / build-windows (push) Successful in 3m28s
Build App / build-linux (push) Successful in 5m21s
Build App / create-tag (push) Successful in 3s
Build App / sync-to-github (push) Has been cancelled
The version comparison was only comparing the patch number, ignoring major
and minor versions. This meant 0.1.75 (patch=75) appeared "newer" than
0.2.1 (patch=1), and updates within 0.2.x were missed entirely.

Also fixed platform filtering to handle -mac suffix (previously only
filtered -win, so Linux users would see macOS releases too).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 09:45:43 -07:00

View File

@@ -34,30 +34,37 @@ pub async fn check_for_updates() -> Result<Option<UpdateInfo>, String> {
.map_err(|e| format!("Failed to parse releases: {}", e))?; .map_err(|e| format!("Failed to parse releases: {}", e))?;
let current_version = env!("CARGO_PKG_VERSION"); let current_version = env!("CARGO_PKG_VERSION");
let is_windows = cfg!(target_os = "windows"); let current_semver = parse_semver(current_version).unwrap_or((0, 0, 0));
// Determine platform suffix for tag filtering
let platform_suffix: &str = if cfg!(target_os = "windows") {
"-win"
} else if cfg!(target_os = "macos") {
"-mac"
} else {
"" // Linux uses bare tags (no suffix)
};
// Filter releases by platform tag suffix // Filter releases by platform tag suffix
let platform_releases: Vec<&GiteaRelease> = releases let platform_releases: Vec<&GiteaRelease> = releases
.iter() .iter()
.filter(|r| { .filter(|r| {
if is_windows { if platform_suffix.is_empty() {
r.tag_name.ends_with("-win") // Linux: bare tag only (no -win, no -mac)
!r.tag_name.ends_with("-win") && !r.tag_name.ends_with("-mac")
} else { } else {
!r.tag_name.ends_with("-win") r.tag_name.ends_with(platform_suffix)
} }
}) })
.collect(); .collect();
// Find the latest release with a higher patch version // Find the latest release with a higher semver version
// Version format: 0.1.X or v0.1.X (tag may have prefix/suffix) let mut best: Option<(&GiteaRelease, (u32, u32, u32))> = None;
let current_patch = parse_patch_version(current_version).unwrap_or(0);
let mut best: Option<(&GiteaRelease, u32)> = None;
for release in &platform_releases { for release in &platform_releases {
if let Some(patch) = parse_patch_from_tag(&release.tag_name) { if let Some(ver) = parse_semver_from_tag(&release.tag_name) {
if patch > current_patch { if ver > current_semver {
if best.is_none() || patch > best.unwrap().1 { if best.is_none() || ver > best.unwrap().1 {
best = Some((release, patch)); best = Some((release, ver));
} }
} }
} }
@@ -92,36 +99,34 @@ pub async fn check_for_updates() -> Result<Option<UpdateInfo>, String> {
} }
} }
/// Parse patch version from a semver string like "0.1.5" -> 5 /// Parse a semver string like "0.2.5" -> (0, 2, 5)
fn parse_patch_version(version: &str) -> Option<u32> { fn parse_semver(version: &str) -> Option<(u32, u32, u32)> {
let clean = version.trim_start_matches('v'); let clean = version.trim_start_matches('v');
let parts: Vec<&str> = clean.split('.').collect(); let parts: Vec<&str> = clean.split('.').collect();
if parts.len() >= 3 { if parts.len() >= 3 {
parts[2].parse().ok() let major = parts[0].parse().ok()?;
let minor = parts[1].parse().ok()?;
let patch = parts[2].parse().ok()?;
Some((major, minor, patch))
} else { } else {
None None
} }
} }
/// Parse patch version from a tag like "v0.1.5", "v0.1.5-win", "0.1.5" -> 5 /// Parse semver from a tag like "v0.2.5", "v0.2.5-win", "v0.2.5-mac" -> (0, 2, 5)
fn parse_patch_from_tag(tag: &str) -> Option<u32> { fn parse_semver_from_tag(tag: &str) -> Option<(u32, u32, u32)> {
let clean = tag.trim_start_matches('v'); let clean = tag.trim_start_matches('v');
// Remove platform suffix // Remove platform suffix
let clean = clean.strip_suffix("-win").unwrap_or(clean); let clean = clean.strip_suffix("-win")
parse_patch_version(clean) .or_else(|| clean.strip_suffix("-mac"))
.unwrap_or(clean);
parse_semver(clean)
} }
/// Extract a clean version string from a tag like "v0.1.5-win" -> "0.1.5" /// Extract a clean version string from a tag like "v0.2.5-win" -> "0.2.5"
fn extract_version_from_tag(tag: &str) -> Option<String> { fn extract_version_from_tag(tag: &str) -> Option<String> {
let clean = tag.trim_start_matches('v'); let (major, minor, patch) = parse_semver_from_tag(tag)?;
let clean = clean.strip_suffix("-win").unwrap_or(clean); Some(format!("{}.{}.{}", major, minor, patch))
// Validate it looks like a version
let parts: Vec<&str> = clean.split('.').collect();
if parts.len() >= 3 && parts.iter().all(|p| p.parse::<u32>().is_ok()) {
Some(clean.to_string())
} else {
None
}
} }
/// Check whether a newer container image is available in the registry. /// Check whether a newer container image is available in the registry.