From 48c024f69b0d2919626abbb92d04c0623ee2b512 Mon Sep 17 00:00:00 2001 From: librelad Date: Wed, 19 Aug 2026 03:02:12 +0100 Subject: [PATCH] fix(updater): stop the version display contradicting itself MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two display bugs the newer-version work made visible. A fleet row showed a green "✓ Up to date" directly beside a "1.159.0 available" chip. Both statements are individually true — you ARE current on the line you track, and changing lines is a deliberate act — but a row is a glance, not a place to reconcile two chips that appear to disagree. The green all-clear now gives way to a neutral "Newer version" whenever a newer release line exists; the chip still carries the number and the tooltip still explains the move. The per-app detail deliberately keeps "up to date" and is left alone: there the badge arrives with a sentence explaining the distinction and an Upgrade button, which is what makes it readable. updaterDisplayVersion preferred the OCI version label unconditionally. That label is inherited from the vendor's base image unless they overwrite it, so it can describe the OS rather than the app: mongo:8.0 carries org.opencontainers.image.version=24.04, its Ubuntu base, and Stoat's row read "24.04 → 8.0 · 02a0cc7" — not a version transition at all. When the tracked tag is versioned we already hold an authoritative version, so the label now wins only if the two agree on their leading number. Keeps nextcloud 34 → 34.0.1, rejects mongo 8.0 vs 24.04, and leaves rolling tags untouched since the label is the whole point there. Co-Authored-By: Claude Opus 5 --- .../apps/overview/js/overview-manager.js | 14 +++++++++++- .../generators/updater/webui_updater_scan.sh | 22 +++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/containers/libreportal/frontend/components/apps/overview/js/overview-manager.js b/containers/libreportal/frontend/components/apps/overview/js/overview-manager.js index 77a4531..c2e0c41 100644 --- a/containers/libreportal/frontend/components/apps/overview/js/overview-manager.js +++ b/containers/libreportal/frontend/components/apps/overview/js/overview-manager.js @@ -607,9 +607,21 @@ class OverviewManager { const name = esc((window.getAppDisplayName ? window.getAppDisplayName(a.name) : null) || a.displayName || a.name); const cur = esc(a.current_version || a.current_image || '—'); const avail = a.update_available ? esc(a.available_version || a.available_image || 'newer') : null; + // "✓ Up to date" is the whole truth only when nothing newer exists at all. + // Once a newer release line is published, a green all-clear sitting beside + // the "1.159.0 available" chip reads as a flat contradiction. The two ARE + // reconcilable — you are current on the line you track, and moving lines is + // a deliberate act — but a fleet row is a glance, not a place to reconcile + // anything. So drop the reassurance and let the chip carry the specifics. + // (The per-app detail keeps "up to date" on purpose: there it comes with a + // sentence explaining the distinction and an Upgrade button.) const status = a.update_available ? `↑ Update available` - : (a.scanned ? `✓ Up to date` : `• Unscanned`); + : (!a.scanned + ? `• Unscanned` + : (a.newer_version + ? `• Newer version` + : `✓ Up to date`)); const sev = a.worstSeverity ? `${a.worstSeverity}` : ''; // Automatic is the default, so only the apps that opt OUT carry a marker — // 30-odd "auto" chips would be wallpaper, one "manual" chip is information. diff --git a/scripts/webui/data/generators/updater/webui_updater_scan.sh b/scripts/webui/data/generators/updater/webui_updater_scan.sh index ea3928d..e8c7662 100644 --- a/scripts/webui/data/generators/updater/webui_updater_scan.sh +++ b/scripts/webui/data/generators/updater/webui_updater_scan.sh @@ -290,6 +290,28 @@ updaterNewerVersionTag() { # Human-readable version for display: OCI label → tag (versioned) → tag·shortdigest. updaterDisplayVersion() { local oci="$1" channel="$2" vtype="$3" digest="$4" + # The OCI version label is usually the app's own version and reads far + # better than a bare tag ("0.63.2" beats "latest"), which is why it wins. + # But that label is INHERITED from whichever base image the vendor built on + # unless they overwrite it, so it can describe the OS instead of the app: + # mongo:8.0 carries org.opencontainers.image.version=24.04 — its Ubuntu + # base — and the row then called MongoDB "24.04" and offered "24.04 → 8.0" + # as an upgrade, which is not a version transition at all. + # + # When we track a VERSIONED tag we already hold an authoritative statement + # of the app's version, so the label only wins if the two agree on their + # leading number. That keeps the richer label where it genuinely is the + # app's (nextcloud 34 → 34.0.1) and rejects it where it plainly is not + # (mongo 8.0 vs 24.04). Rolling tags are unaffected: there is no version in + # "latest" to check against, and the label is the whole point there. + if [ -n "$oci" ] && [ "$vtype" = "versioned" ] && [ -n "$channel" ]; then + local _ln _cn + _ln="$(printf '%s' "$oci" | grep -oE '[0-9]+' | head -1)" + _cn="$(printf '%s' "$channel" | grep -oE '[0-9]+' | head -1)" + if [ -n "$_ln" ] && [ -n "$_cn" ] && [ "$((10#$_ln))" != "$((10#$_cn))" ]; then + oci="" + fi + fi if [ -n "$oci" ]; then printf '%s' "$oci"; return; fi if [ "$vtype" = "versioned" ] && [ -n "$channel" ]; then printf '%s' "$channel"; return; fi local short="${digest#sha256:}"; short="${short:0:7}"