From 7ebdc9c72264cfe9e8ccc7c09150211f3dcd6b11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaroslav=20Bene=C5=A1?= Date: Fri, 7 Aug 2026 15:33:32 +0200 Subject: [PATCH] A version that was not two spellings of itself The Updates page read "v1.0.0 (reports 1.0.0)". That note exists to warn that a tag was cut before the version bump -- a release nobody can identify afterwards -- and it was firing on two ways of writing one version, because `git describe` answers with the tag's name and tags here carry a `v`. Stripped in `_describe`, where `resolve_target` has always stripped it and where the docstring already promised the stripped form. The mismatch check then compares two things spelled the same way, and still reports a tag that really does disagree; there is a test for each half. Found by cutting the first release, which is the only place it could have been found. Co-Authored-By: Claude Opus 5 (1M context) --- CHANGELOG.md | 8 ++++++++ src/lembas/__init__.py | 2 +- src/lembas/services/updates.py | 15 ++++++++++---- tests/test_updates.py | 36 ++++++++++++++++++++++++++++++++++ 4 files changed, 56 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a8d1c2b..a78ca00 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,14 @@ for 1.0.0 have something to be assembled from. ## Unreleased +## 1.0.1 + +- Fixed: the Updates page showed **"v1.0.0 (reports 1.0.0)"** — two spellings of + one version, in a note whose whole purpose is to warn that a tag was cut + before the version bump. `git describe` answers with the tag's name, and tags + here carry a `v`. Found by cutting the first release, which is the only place + it could have been. + ## 1.0.0 The first release. Every version before it shipped as a running deployment diff --git a/src/lembas/__init__.py b/src/lembas/__init__.py index b334b13..056cc7a 100644 --- a/src/lembas/__init__.py +++ b/src/lembas/__init__.py @@ -1,3 +1,3 @@ """LLeMbas - a Middle-earth themed web UI for OpenAI-compatible LLM endpoints.""" -__version__ = "1.0.0" +__version__ = "1.0.1" diff --git a/src/lembas/services/updates.py b/src/lembas/services/updates.py index d664845..6ff4869 100644 --- a/src/lembas/services/updates.py +++ b/src/lembas/services/updates.py @@ -340,7 +340,7 @@ def resolve_target(root: Path, channel: str, branch: str) -> Target | None: return None return Target( ref=tag, - label=tag.lstrip("v"), + label=tag.removeprefix("v"), sha=commit.sha, subject=commit.subject, notes=_notes_for(root, tag), @@ -362,9 +362,16 @@ def _describe(root: Path) -> str: bare short sha when nothing has ever been tagged. That last case is why `--always` is there: without it this fails outright on a repository with no tags, which is every repository before its first release. + + The leading `v` comes off, because git answers with the **tag's name** and + tags here are `v1.0.0` while `__version__` is `1.0.0`. Without this the page + read "v1.0.0 (reports 1.0.0)" -- a note whose whole purpose is to flag a tag + cut before a version bump, firing on two spellings of the same version. The + first release is what showed it. `resolve_target` has always stripped it for + the same reason, and this docstring already promised the stripped form. """ code, output = _git(["describe", "--tags", "--always", "--dirty="], cwd=root) - return output if code == 0 else "" + return output.removeprefix("v") if code == 0 else "" def read(*, fetch: bool = False) -> State: @@ -418,8 +425,8 @@ def read(*, fetch: bool = False) -> State: # Exactly at a tag whose name disagrees with the version this process # reports. No subprocess: `running` and `__version__` are both already here. mismatch = "" - if RELEASE_TAG.match(running) and running.lstrip("v") != __version__: - mismatch = running.lstrip("v") + if RELEASE_TAG.match(running) and running != __version__: + mismatch = running return State( **base, diff --git a/tests/test_updates.py b/tests/test_updates.py index e5b1863..ce88e47 100644 --- a/tests/test_updates.py +++ b/tests/test_updates.py @@ -509,3 +509,39 @@ def test_a_reinstall_does_not_move_the_channel_by_itself(): assert 'CHANNEL="${LEMBAS_CHANNEL:-${_installed_channel:-stable}}"' in install # Parsed rather than sourced: that file holds the secret key. assert ". $PREFIX/lembas.env" not in install + + +def test_the_running_version_is_not_two_spellings_of_itself(db, tagged): + """`git describe` answers with the **tag's name**, and tags here are + `v1.0.0` while `__version__` is `1.0.0`. The page prints the described + version and appends "(reports X)" when the two disagree -- a note whose + whole purpose is to flag a tag cut *before* a version bump. + + Unstripped, it fired on the first release: "v9.9.9 (reports 9.9.9)", which + reads as a discrepancy and is two ways of writing one version. Found by + cutting the release, which is the only place it could have been. + """ + root = updates.checkout_dir() + running = updates._describe(root) + + assert not running.startswith("v"), running + assert running.startswith("9.9.9"), running + + +def test_a_tag_that_really_disagrees_is_still_reported(db): + """The note has to keep working, or stripping the prefix has removed the + check rather than fixed it. A tag cut before the version bump names a + release nobody can identify afterwards.""" + import subprocess + + root = updates.checkout_dir() + subprocess.run( + ["git", "tag", "-a", "v99.0.0", "-m", "Wrong."], + cwd=root, check=True, capture_output=True, + ) + try: + assert updates.read().version_mismatch == "99.0.0" + finally: + subprocess.run( + ["git", "tag", "-d", "v99.0.0"], cwd=root, check=False, capture_output=True + )