From b27c2b6e8468ede358b56defc9baa770b5d57984 Mon Sep 17 00:00:00 2001 From: Hermes Team Date: Mon, 31 Aug 2026 19:17:57 +0700 Subject: [PATCH] =?UTF-8?q?fix(updater):=20=D0=BA=D0=BD=D0=BE=D0=BF=D0=BA?= =?UTF-8?q?=D0=B0=20=D0=BE=D0=B1=D0=BD=D0=BE=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8?= =?UTF-8?q?=D1=8F=20=D1=81=D1=82=D0=B0=D0=B2=D0=B8=D0=BB=D0=B0=20=D0=BE?= =?UTF-8?q?=D1=82=D0=BA=D0=B0=D1=82=20=D0=BF=D1=80=D0=BE=D0=B3=D1=80=D0=B0?= =?UTF-8?q?=D0=BC=D0=BC=D1=8B=20=D0=BD=D0=B0=D0=B7=D0=B0=D0=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Сравнение сборок шло только на равенство коммитов: любое расхождение объявлялось обновлением. Последний релиз на 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 --- .../updater/update_manager.py | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/src/antigravity_provider/updater/update_manager.py b/src/antigravity_provider/updater/update_manager.py index f15c4e4..14aeb35 100644 --- a/src/antigravity_provider/updater/update_manager.py +++ b/src/antigravity_provider/updater/update_manager.py @@ -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: """Return currently installed git commit hash, checking deployment manifest, env, and git.""" # 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): update_available = False message = "Установлена последняя сборка" + elif _is_release_older(published_at, get_installed_build_time()): + # Коммиты разные, но релиз старше установленной сборки — + # это откат назад, а не обновление. + update_available = False + message = ( + f"Установлена сборка новее опубликованного релиза " + f"({lat_clean[:7]} от {published_at[:10]})" + ) else: update_available = True message = f"Доступно обновление (сборка {lat_clean[:7]})"