Files
hermes-agent/tests/hermes_cli/test_dump_git_commit.py
ethernet c13ea774e6 refactor: make install-stamp.json the single runtime version identity
Runtime identity resolved through hermes_cli.__version__ (a static 0.0.0
on source installs, rewritten by release stamping) leaked v0.0.0 into
About, /api/health, User-Agents, and plugin compat, and source updates
showed "couldn't reach update server" because identity and channel
authority disagreed with the checkout.

Now: get_version_info() resolves install stamp -> live git -> unknown,
never pyproject metadata, never a package constant. Source checkouts
derive identity from their reachable release tag; the completion tail of
every successful install/update/historical takeover atomically rewrites
install-stamp.json with that identity; a stale source stamp whose commit
no longer matches HEAD defers to live git. ACP/TUI use derived_version
for display and base_version for protocol fields; all ~44 runtime
__version__ consumers migrated; hermes_cli.__version__ and generated
_version.py are gone; release stamping only touches the native manifests
external builders consume (nix/tauri/cargo) and passes release identity
straight into write_install_stamp.py; pyproject.toml stays inert 0.0.0.
Desktop no longer synthesizes a competing install-stamp.json: the
checkout owns its stamp, and desktop-bootstrap classification keys on
the bootstrap-complete marker. verify-bootstrap-version-stamp.py now
cross-checks the checkout's stamp (baseVersion + commit == HEAD).

Validation: 31-file focused suite green (version identity, stamping,
adoption, providers, gateway, acp/tui runtime identity, api server via
extras env, release graph); desktop tsc + 25 vitest green; real-repo
probe: base=unknown derived=git.0635606.dirty source=git on this
checkout; clean-env imports resolve entirely from this tree; windows
footgun + compat-pointer scans clean.
2026-09-23 11:41:01 -04:00

108 lines
4.0 KiB
Python

"""Tests for hermes_cli.dump._get_git_commit — git SHA resolution for ``hermes dump``.
``hermes dump`` prints the running commit so support bug reports identify the
exact version. Source installs resolve it live via git; packaged builds
(Docker, Nix) use the install stamp via ``version_info`` — but ONLY when the
requested project_root IS the running install, because version_info has no
per-root API and would otherwise answer with an unrelated install's identity.
These tests cover both paths plus the failure modes (no stamp, no git, and a
project_root the running install cannot speak for).
"""
from pathlib import Path
from subprocess import run as _run
from unittest.mock import patch
import pytest
from hermes_cli.version_info import VersionInfo, _reset_version_info_cache
def setup_function():
_reset_version_info_cache()
@pytest.mark.parametrize('sha,timestamp,expected,date', [
('cafef00d' * 5, 1718662620, 'cafef00d', '2024-06-17'),
(None, None, '(unknown)', ''),
])
def test_dump_uses_running_install_fallback_only(tmp_path, monkeypatch, sha, timestamp, expected, date):
from hermes_cli import dump
monkeypatch.setattr(dump, 'get_project_root', lambda: tmp_path)
info = VersionInfo('1.0', '1.0', None, sha, None, 'docker', False, timestamp)
monkeypatch.setattr('hermes_cli.version_info.get_version_info', lambda: info)
assert dump._get_git_commit(tmp_path) == expected
assert dump._get_git_commit_date(tmp_path) == date
def test_dump_version_line_uses_derived_runtime_version(tmp_path, monkeypatch):
from hermes_cli import dump
info = VersionInfo(
"1.2.3", "1.2.3+4.gabcdef0", 4, "abcdef0" * 5 + "abcde", "main", "git"
)
monkeypatch.setattr("hermes_cli.version_info.get_version_info", lambda: info)
monkeypatch.setattr(dump, "_get_git_commit", lambda _root: "abcdef0")
monkeypatch.setattr(dump, "_get_git_commit_date", lambda _root: "")
assert dump._version_line(tmp_path) == "1.2.3+4.gabcdef0 [abcdef0]"
# --------------------------------------------------------------------------
# Authority: the requested project_root decides, never the running install
# --------------------------------------------------------------------------
def test_get_git_commit_unknown_for_other_root_without_git(tmp_path):
"""A non-git project_root that is NOT the running install → '(unknown)'.
No mocks: the running install (this checkout) HAS git provenance, so the
pre-authority fallback would have answered with THIS repo's sha — an
unrelated install's identity — instead of admitting unknown.
"""
from hermes_cli import dump
other_root = tmp_path / "plain-dir"
other_root.mkdir()
assert (other_root / ".git").exists() is False
commit = dump._get_git_commit(other_root)
assert commit == "(unknown)"
def test_get_git_commit_authoritative_for_real_temp_repo(tmp_path):
"""A real temp git repo reports ITS OWN commit, not the running install's."""
from hermes_cli import dump
repo_dir = tmp_path / "scratch-repo"
repo_dir.mkdir()
(repo_dir / "file.txt").write_text("x", encoding="utf-8")
for args in (
["init", "-b", "main"],
["-c", "user.email=t@example.com", "-c", "user.name=t", "add", "."],
["-c", "user.email=t@example.com", "-c", "user.name=t",
"commit", "-m", "scratch", "--no-gpg-sign"],
):
_run(["git", *args], cwd=repo_dir, capture_output=True, check=True)
expected = _run(["git", "rev-parse", "--short=8", "HEAD"], cwd=repo_dir,
capture_output=True, text=True, check=True).stdout.strip()
commit = dump._get_git_commit(repo_dir)
assert commit == expected
assert commit != dump._get_git_commit(Path(dump.__file__).parent.parent)
def test_get_git_commit_date_unknown_for_other_root_without_git(tmp_path):
"""Same authority rule for the date helper: other root without git → ''."""
from hermes_cli import dump
other_root = tmp_path / "plain-dir"
other_root.mkdir()
assert dump._get_git_commit_date(other_root) == ""