fix(update): refresh release tags before stamping source versions
This commit is contained in:
@@ -391,19 +391,18 @@ def prune_stale_shallow_grafts(repo_root: Path) -> int:
|
||||
|
||||
|
||||
def fetch_full_commit_graph(repo_root: Path, **run_kwargs) -> bool:
|
||||
"""Turn a shallow checkout into a treeless partial clone of ``origin``.
|
||||
"""Refresh release tags and fill shallow history before publishing identity.
|
||||
|
||||
Version identity is the nearest reachable release tag plus the commit count since
|
||||
it, and a shallow boundary hides both. Only commits (and the tags that follow
|
||||
them) are fetched; trees and blobs stay on demand, so this costs a fraction of a
|
||||
full unshallow. Returns False when the checkout was not shallow; raises
|
||||
``subprocess.CalledProcessError`` / ``TimeoutExpired`` when the fetch fails.
|
||||
A full commit graph does not imply current tags, especially after a --no-tags
|
||||
clone. Fetch version tags explicitly without fetching every remote branch or
|
||||
replacing existing tags. Trees and blobs stay on demand. Returns whether the
|
||||
checkout was unshallowed; fetch failures raise subprocess errors.
|
||||
"""
|
||||
if _shallow_file_path(repo_root) is None:
|
||||
return False
|
||||
shallow = _shallow_file_path(repo_root) is not None
|
||||
subprocess.run(
|
||||
["git", "fetch", "--quiet", "--unshallow", "--filter=tree:0", "origin"],
|
||||
["git", "fetch", "--quiet", *(["--unshallow"] if shallow else []),
|
||||
"--filter=tree:0", "--no-tags", "origin", "refs/tags/v*:refs/tags/v*"],
|
||||
cwd=str(repo_root), check=True, capture_output=True, text=True,
|
||||
encoding="utf-8", errors="replace", timeout=900, **run_kwargs,
|
||||
)
|
||||
return True
|
||||
return shallow
|
||||
|
||||
@@ -990,9 +990,8 @@ def _run_post_update_maintenance(
|
||||
with _best_effort('Post-update state.db integrity check failed: %s'):
|
||||
_verify_and_restore_state_dbs_post_update()
|
||||
|
||||
# Pre-PM installers cloned --depth 1, which hides the release tag identity is
|
||||
# derived from. Fetch the commit graph before the completion line and the
|
||||
# install stamp read that identity.
|
||||
# Both shallow history and missing tags can hide the release identity.
|
||||
# Refresh them before the completion line and install stamp read it.
|
||||
try:
|
||||
from hermes_cli.gitlock import fetch_full_commit_graph
|
||||
from hermes_cli.update_cmd import _no_prompt_git_kwargs
|
||||
@@ -1000,7 +999,7 @@ def _run_post_update_maintenance(
|
||||
print(" ✓ Fetched release history (commits only) for version identity")
|
||||
except (OSError, subprocess.SubprocessError) as exc:
|
||||
detail = (getattr(exc, "stderr", None) or str(exc)).strip().splitlines()[-1:] or [type(exc).__name__]
|
||||
print(f" ⚠ Could not fetch release history ({detail[0]}); the version shows as git.<sha> until the next update")
|
||||
print(f" ⚠ Could not refresh release history ({detail[0]}); the version label may be stale or unknown until the next update")
|
||||
|
||||
# Seed the model-catalog cache from the checkout instead of a bot-gated, flaky fetch.
|
||||
with _best_effort('Model catalog seed during update failed: %s'):
|
||||
|
||||
@@ -108,3 +108,41 @@ def test_shallow_checkout_publishes_its_release_after_fetching_the_commit_graph(
|
||||
assert stamp is not None
|
||||
assert (stamp["baseVersion"], stamp["distance"]) == ("0.21.4", 3)
|
||||
assert not fetch_full_commit_graph(checkout)
|
||||
|
||||
|
||||
def test_full_checkout_refreshes_release_tags_before_publishing_identity(tmp_path):
|
||||
from hermes_cli.gitlock import fetch_full_commit_graph
|
||||
|
||||
server = _repo(tmp_path)
|
||||
env = {"HOME": str(tmp_path), "PATH": os.environ["PATH"]}
|
||||
|
||||
def git(root: Path, *args: str) -> str:
|
||||
return subprocess.run(
|
||||
["git", *args], cwd=root, env=env, check=True, capture_output=True, text=True,
|
||||
).stdout.strip()
|
||||
|
||||
git(server, "config", "uploadpack.allowFilter", "true")
|
||||
git(server, "tag", "-d", "v0.21.4")
|
||||
versions = (("v2026.9.7", "0.21.1"), ("v2026.9.24", "0.21.5"))
|
||||
for tag, version in versions:
|
||||
(server / "pyproject.toml").write_text(f'[project]\nversion = "{version}"\n', encoding="utf-8")
|
||||
git(server, "add", "pyproject.toml")
|
||||
git(server, "commit", "-qm", "release")
|
||||
git(server, "tag", tag)
|
||||
git(server, "commit", "-q", "--allow-empty", "-m", "after release")
|
||||
checkout = tmp_path / "checkout"
|
||||
git(server, "clone", "-q", "--no-tags", server.as_uri(), str(checkout))
|
||||
old_tag, old_version = versions[0]
|
||||
git(checkout, "fetch", "-q", "origin", f"refs/tags/{old_tag}:refs/tags/{old_tag}")
|
||||
commit = git(checkout, "rev-parse", "HEAD")
|
||||
assert git(checkout, "rev-parse", "--is-shallow-repository") == "false"
|
||||
before = write_source_stamp(checkout)
|
||||
assert before is not None
|
||||
assert before["baseVersion"] == old_version
|
||||
|
||||
fetch_full_commit_graph(checkout)
|
||||
stamp = write_source_stamp(checkout)
|
||||
|
||||
assert stamp is not None
|
||||
assert (stamp["baseVersion"], stamp["distance"]) == (versions[1][1], 1)
|
||||
assert stamp["commit"] == commit == git(checkout, "rev-parse", "HEAD")
|
||||
|
||||
Reference in New Issue
Block a user