fix: normalize update banner repository URLs

This commit is contained in:
Michael Lam
2026-05-05 08:29:00 -07:00
parent 1cde702d47
commit dc7ba0c845
2 changed files with 45 additions and 5 deletions
+20 -5
View File
@@ -150,6 +150,25 @@ WEBUI_VERSION: str = _detect_webui_version()
AGENT_VERSION: str = _detect_agent_version()
def _normalize_remote_url(remote_url):
"""Return the browser-facing repository URL for update compare links.
Git remotes may be HTTPS or SSH and may include a literal ``.git`` suffix.
Strip only that literal suffix — never use ``str.rstrip('.git')`` because it
treats the argument as a character set and can truncate ``hermes-webui`` to
``hermes-webu``.
"""
if not remote_url:
return remote_url
remote_url = remote_url.strip()
if remote_url.startswith('git@'):
remote_url = remote_url.replace(':', '/', 1).replace('git@', 'https://', 1)
remote_url = remote_url.rstrip('/')
if remote_url.endswith('.git'):
remote_url = remote_url[:-4]
return remote_url.rstrip('/')
def _split_remote_ref(ref):
"""Split 'origin/branch-name' into ('origin', 'branch-name').
@@ -234,11 +253,7 @@ def _check_repo(path, name):
# Get repo URL for "What's new?" link
remote_url, _ = _run_git(['remote', 'get-url', 'origin'], path)
# Convert SSH URLs (git@github.com:org/repo.git) to HTTPS
if remote_url and remote_url.startswith('git@'):
remote_url = remote_url.replace(':', '/', 1).replace('git@', 'https://', 1)
if remote_url and remote_url.endswith('.git'):
remote_url = remote_url[:-4]
remote_url = _normalize_remote_url(remote_url)
return {
'name': name,
+25
View File
@@ -79,6 +79,31 @@ class TestUpdateChecker:
assert result['repo_url'] == 'https://github.com/NousResearch/hermes-agent'
def test_repo_url_strips_dot_git_before_trailing_slashes(self, tmp_path, monkeypatch):
import api.updates as upd
(tmp_path / '.git').mkdir()
def fake_run(args, cwd, timeout=10):
if args[0] == 'fetch':
return '', True
if args[:2] == ['rev-parse', '--abbrev-ref']:
return 'origin/master', True
if args[:2] == ['rev-list', '--count']:
return '2', True
if args[0] == 'merge-base':
return 'abcdef1234567890', True
if args[:2] == ['rev-parse', '--short']:
return 'abcdef1', True
if args[:2] == ['remote', 'get-url']:
return 'https://github.com/nesquena/hermes-webui.git/', True
return '', True
monkeypatch.setattr(upd, '_run_git', fake_run)
result = upd._check_repo(tmp_path, 'webui')
assert result['repo_url'] == 'https://github.com/nesquena/hermes-webui'
class TestConflictError:
"""#813 — conflict error must include flag + recovery command."""