Files
Serena Ruan aec304df87 fix(version): single source of truth for the omnigent version (#1772)
* fix(version): single source of truth for the omnigent version

The host and runner hard-coded version="0.1.0" in their hello frames,
so every host/runner reported a stale placeholder in the server's
version popover regardless of the build actually running. The server
had its own metadata->pyproject->PEP440 fallback to cope with installs
whose package metadata reports a non-PEP-440 "source" placeholder.

Introduce omnigent/version.py holding a single VERSION constant that the
runtime imports directly (no importlib.metadata round-trip), and wire the
host hello frame, runner hello frame, server /api/version, and CLI
--version to it. Importing the constant is correct regardless of how the
package was installed, so the server's fallback dance is deleted.

VERSION mirrors the canonical [project].version in pyproject.toml; a
pre-commit fixer (scripts/sync_version_py.py) rewrites the constant to
match pyproject and aborts the commit for re-staging on drift, so
releases stay a pyproject-only bump (via scripts/update_versions.py).

Co-authored-by: Isaac

* fix(version): teach the release bump path about omnigent/version.py

Polly review on #1772: the automated bump path (scripts/update_versions.py
+ .github/workflows/bump-version.yml) rewrote only the three pyproject.toml
files, never omnigent/version.py, and its `check` verified only the
pyprojects. A bot bump would therefore commit a stale VERSION constant and
trip the new test_version_matches_pyproject backstop — breaking the
"pyproject-only bump" story this change relies on.

Extend set_version() to also stamp the VERSION constant in
omnigent/version.py (anchored on its own `VERSION = "..."` line), and
extend check() to verify the constant equals the resolved [project].version
so a forgotten bump fails in the release tooling rather than on the bot PR.
The workflow's `git add -A` already picks up the extra file, so no YAML
logic change is needed — only the descriptive comment/PR body are updated.

Also soften sync_version_py.py's --check docstring, which implied a CI
wiring that never existed (per the review's non-blocking note).

Co-authored-by: Isaac

* test(version): don't assert /api/version against frozen package metadata

Polly review on #1772: the server version tests re-added
`== importlib.metadata.version("omnigent")` assertions. Since pyproject's
version is static (no dynamic wiring), that metadata is a frozen build-time
snapshot that can legitimately differ from VERSION — a stale editable
install or a "source" placeholder — the exact cases the removed server
fallback handled. Equality only holds right after a clean reinstall, so the
assertions are a latent spurious failure that undercuts the PR's
"authoritative regardless of how the package was installed" contract.

Drop the `_pkg_version` assertions in test_version_returns_source_of_truth_version
and test_info_includes_server_version (keep `== VERSION`), and remove the now
-unused import.

Also address non-blocking note 1: the --version banner (format_help) now reads
VERSION instead of importlib.metadata, for consistency with `--version`. The
upgrade path (cli.py) intentionally keeps reading installed metadata — it must
compare the on-disk install against PyPI.

Co-authored-by: Isaac
2026-07-01 17:31:20 +08:00

42 lines
1.4 KiB
Python

"""Tests for the version source of truth (``omnigent.version``)."""
from __future__ import annotations
from pathlib import Path
import tomllib
from omnigent.version import VERSION
def test_version_is_a_nonempty_string() -> None:
"""``VERSION`` is the exported source-of-truth constant."""
assert isinstance(VERSION, str)
assert VERSION
def test_version_is_pep440() -> None:
"""The literal must be a valid PEP 440 version — the build ships it as-is."""
from packaging.version import Version
# Raises InvalidVersion if the literal is malformed.
Version(VERSION)
def test_version_matches_pyproject() -> None:
"""``VERSION`` must equal ``pyproject.toml``'s canonical ``[project].version``.
``scripts/sync_version_py.py`` (a pre-commit fixer) keeps them equal; this
is the CI backstop that catches a commit made without the hook.
"""
pyproject = Path(__file__).resolve().parent.parent / "pyproject.toml"
if not pyproject.is_file():
# Running from an installed wheel with no source tree — nothing to check.
return
data = tomllib.loads(pyproject.read_text(encoding="utf-8"))
pyproject_version = data["project"]["version"]
assert pyproject_version == VERSION, (
f"pyproject.toml version {pyproject_version!r} != omnigent.version.VERSION "
f"{VERSION!r}; run `python scripts/sync_version_py.py`"
)