Add display_version field to repo version info for non-release commits

Add display_version to get_repo_version_info output that shows tag+commits (e.g. "v1.11+9") for development builds. Update self-update UI to prefer display_version over short_tag for current version display. Add describe field to modal when it differs from short_tag. Add test coverage for display_version generation on non-main branches.

frdel committed Mar 26, 2026 at 12:47 UTC 2a47410e17c1fb67c07328bd68815cd755582424
4 files changed +29 -1
helpers/self_update.py
+1
@@ -198,6 +198,7 @@ def get_repo_version_info(repo_dir: str | Path | None = None) -> dict[str, str]:
198 "branch": branch,
199 "describe": describe,
200 "short_tag": _normalize_describe_to_version(describe),
201 + "display_version": _format_branch_head_version(branch, describe),
202 "commit": commit,
203 "short_commit": commit[:7],
204 }
tests/test_self_update_tag_filter.py
+21
@@ -296,6 +296,7 @@ def test_self_update_update_info_uses_current_branch_for_latest_version(monkeypa
296 "branch": "main",
297 "describe": "v1.2",
298 "short_tag": "v1.2",
299 + "display_version": "v1.2",
300 "commit": "abc1234def",
301 "short_commit": "abc1234",
302 },
@@ -388,6 +389,7 @@ def test_self_update_frontend_uses_preloaded_select():
389 assert "isLatestSelectorTag(value)" in content
390 assert "this.isSelectableTag(this.form.tag)" in content
391 assert "getLastStatusBadgeClass(status)" in content
392 + assert "this.info?.current?.display_version" in content
393 assert "status-pill-error" in content
394 assert "status-pill-success" in content
395 assert "this.info?.defaults?.branch ||" in content
@@ -422,6 +424,7 @@ def test_self_update_modal_uses_standard_select_and_manual_backup():
424 assert "$store.selfUpdateStore.versionSelectPlaceholder" in content
425 assert "$store.selfUpdateStore.higherMajorVersionMessage" in content
426 assert "$store.selfUpdateStore.availableTagOptions" in content
427 + assert "$store.selfUpdateStore.info?.current?.describe" in content
428 assert "current_branch_latest?.display_version" in content
429 assert "tagOption.label" in content
430 assert 'data-bs-target="#self-update-last-attempt-collapse"' in content
@@ -436,6 +439,24 @@ def test_self_update_modal_uses_standard_select_and_manual_backup():
439 assert "selectTag(tag)" not in content
440
441
442 +def test_self_update_repo_version_info_includes_display_version_for_non_main(monkeypatch, tmp_path):
443 + monkeypatch.setattr(
444 + self_update,
445 + "_run_git",
446 + lambda repo_dir, *args: {
447 + ("describe", "--tags", "--always"): "v1.11-9-gf69147a",
448 + ("rev-parse", "HEAD"): "f69147a123456789",
449 + ("branch", "--show-current"): "development",
450 + }[args],
451 + )
452 +
453 + info = self_update.get_repo_version_info(tmp_path)
454 +
455 + assert info["short_tag"] == "v1.11"
456 + assert info["display_version"] == "v1.11+9"
457 + assert info["short_commit"] == "f69147a"
458 +
459 +
460 def test_self_update_recovery_script_and_docs_are_present():
461 script_path = PROJECT_ROOT / "docker" / "run" / "fs" / "exe" / "trigger_self_update.sh"
462 script_content = script_path.read_text(encoding="utf-8")
webui/components/settings/external/self-update-modal.html
+6
@@ -23,6 +23,12 @@
23 <code x-text="$store.selfUpdateStore.info?.current?.short_commit || 'unknown'"></code>
24 </div>
25 <div class="summary-meta" x-text="`Branch ${$store.selfUpdateStore.currentBranch || 'unknown'}`"></div>
26 + <template x-if="$store.selfUpdateStore.info?.current?.describe && $store.selfUpdateStore.info?.current?.describe !== $store.selfUpdateStore.info?.current?.short_tag">
27 + <div
28 + class="summary-meta"
29 + x-text="$store.selfUpdateStore.info?.current?.describe"
30 + ></div>
31 + </template>
32 </div>
33
34 <div class="self-update-summary-card">
webui/components/settings/external/self-update-store.js
+1 -1
@@ -42,7 +42,7 @@ const model = {
42 },
43
44 get currentVersion() {
45 - return this.info?.current?.short_tag || "unknown";
45 + return this.info?.current?.display_version || this.info?.current?.short_tag || "unknown";
46 },
47
48 get currentBranch() {