fix(updater): кнопка обновления ставила откат программы назад
Сравнение сборок шло только на равенство коммитов: любое расхождение объявлялось обновлением. Последний релиз на GitHub указывал на380c218от 30 августа, у владельца стояла сборка новее — хаб предложил «обновиться» на старый коммит, владелец нажал и получил откат. Добавлена проверка по времени: если релиз опубликован раньше, чем установлена текущая сборка (deployed_at из deployment_manifest.json), это откат, а не обновление. Такой релиз не предлагается, и владельцу пишется, что установлена сборка новее опубликованного релиза. Проверено на фактических данных владельца: релиз380c218от 2026-08-30 против установки от 2026-08-31 даёт update_available=False. Версия остаётся 0.1.1 намеренно, сборки различаются коммитом. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
5c2a0692d3
commit
b27c2b6e84
1 changed files with 47 additions and 0 deletions
|
|
@ -43,6 +43,45 @@ ALLOWED_UPDATE_HOSTS = {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def get_installed_build_time() -> str:
|
||||||
|
"""Время установки текущей сборки из deployment_manifest.json (поле deployed_at).
|
||||||
|
|
||||||
|
Нужно, чтобы отличать более новый релиз от более старого. Сравнение
|
||||||
|
коммитов на равенство этого не умеет: любое расхождение оно объявляет
|
||||||
|
обновлением, включая коммит-предок. Владелец нажимал «Обновить» и
|
||||||
|
получал откат программы назад.
|
||||||
|
"""
|
||||||
|
for mf in (
|
||||||
|
paths.get_repo_root() / "deployment_manifest.json",
|
||||||
|
paths.get_hermes_home() / "plugins" / "antigravity-provider" / "deployment_manifest.json",
|
||||||
|
):
|
||||||
|
try:
|
||||||
|
if mf.is_file():
|
||||||
|
data = json.loads(mf.read_text(encoding="utf-8-sig"))
|
||||||
|
val = str(data.get("deployed_at") or "").strip()
|
||||||
|
if val:
|
||||||
|
return val
|
||||||
|
except Exception as exc:
|
||||||
|
logger.debug("Не удалось прочитать %s: %s", mf, exc)
|
||||||
|
return ""
|
||||||
|
|
||||||
|
|
||||||
|
def _is_release_older(published_at: str, installed_at: str) -> bool:
|
||||||
|
"""True, если релиз опубликован раньше, чем установлена текущая сборка."""
|
||||||
|
if not published_at or not installed_at:
|
||||||
|
return False
|
||||||
|
try:
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
|
def _parse(v: str):
|
||||||
|
return datetime.fromisoformat(v.strip().replace("Z", "+00:00"))
|
||||||
|
|
||||||
|
return _parse(published_at) < _parse(installed_at)
|
||||||
|
except Exception as exc:
|
||||||
|
logger.debug("Не удалось сравнить даты %r и %r: %s", published_at, installed_at, exc)
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
def get_installed_commit() -> str:
|
def get_installed_commit() -> str:
|
||||||
"""Return currently installed git commit hash, checking deployment manifest, env, and git."""
|
"""Return currently installed git commit hash, checking deployment manifest, env, and git."""
|
||||||
# 1. Environment variable override
|
# 1. Environment variable override
|
||||||
|
|
@ -389,6 +428,14 @@ class UpdateManager:
|
||||||
if inst_clean == lat_clean or inst_clean.startswith(lat_clean) or lat_clean.startswith(inst_clean):
|
if inst_clean == lat_clean or inst_clean.startswith(lat_clean) or lat_clean.startswith(inst_clean):
|
||||||
update_available = False
|
update_available = False
|
||||||
message = "Установлена последняя сборка"
|
message = "Установлена последняя сборка"
|
||||||
|
elif _is_release_older(published_at, get_installed_build_time()):
|
||||||
|
# Коммиты разные, но релиз старше установленной сборки —
|
||||||
|
# это откат назад, а не обновление.
|
||||||
|
update_available = False
|
||||||
|
message = (
|
||||||
|
f"Установлена сборка новее опубликованного релиза "
|
||||||
|
f"({lat_clean[:7]} от {published_at[:10]})"
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
update_available = True
|
update_available = True
|
||||||
message = f"Доступно обновление (сборка {lat_clean[:7]})"
|
message = f"Доступно обновление (сборка {lat_clean[:7]})"
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue