fix: проверка готовности всегда врала, установщик показывал зашитую версию
Три дефекта, найденные при установке владельцем на две машины. 1. Linux: лаунчер писал «Web server failed to respond», хотя сервер поднимался нормально — в логе старт API, планировщик квот и прогрев кэша без ошибок. Причина в самой проверке: sys импортировался ТОЛЬКО внутри except, а использовался в успешной ветке. На здоровом ответе возникал NameError, его ловил тот же except, и проверка всегда возвращала отказ. Доказано исполнением на живом сервере: старая логика -> код 1, новая -> код 0. 2. Windows: при нечитаемом манифесте мастер показывал зашитые InstalledVersion = "0.1.0" и InstalledDate = "19.08.2026" как факт. Владелец видел «старую версию» на свежей установке, хотя проверка показала правильный путь и версию 0.1.1. Заглушки заменены на «не определена» — выдуманный факт хуже отсутствующего. 3. Манифест писался одним File.WriteAllText: прерванная запись оставляла пустой файл, и разбор версии падал на первом символе — ровно это и случилось у владельца (JSONDecodeError, char 0). Запись переведена на временный файл с переносом. Попутно: git_commit в манифесте был зашит как "8cddc9f", то есть манифест сообщал неправду о происхождении сборки. Теперь сборщик проставляет фактический коммит. Тесты: 373 passed, ruff чисто. Установщик пересобран. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
36b449bc6c
commit
57e7ca2edd
5 changed files with 37 additions and 9 deletions
|
|
@ -1,4 +1,4 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
|
|
@ -15,6 +15,10 @@ namespace HermesHubSetup
|
||||||
public class SetupEngine
|
public class SetupEngine
|
||||||
{
|
{
|
||||||
public const string HUB_VERSION = "0.1.1";
|
public const string HUB_VERSION = "0.1.1";
|
||||||
|
// Подставляется сборщиком из фактического git-коммита. Раньше здесь
|
||||||
|
// жил зашитый "8cddc9f", то есть манифест сообщал неправду о том, из
|
||||||
|
// какого кода собран установщик.
|
||||||
|
public const string BuildCommit = "36b449b";
|
||||||
public const string MIN_HERMES_VERSION = "0.20.0";
|
public const string MIN_HERMES_VERSION = "0.20.0";
|
||||||
public const string MAX_TESTED_HERMES = "0.20.4";
|
public const string MAX_TESTED_HERMES = "0.20.4";
|
||||||
|
|
||||||
|
|
@ -89,8 +93,12 @@ namespace HermesHubSetup
|
||||||
string installedExe = Path.Combine(TargetInstallDir, "HermesHub.exe");
|
string installedExe = Path.Combine(TargetInstallDir, "HermesHub.exe");
|
||||||
string pluginManifest = Path.Combine(HermesHome, @"plugins\antigravity-provider\deployment_manifest.json");
|
string pluginManifest = Path.Combine(HermesHome, @"plugins\antigravity-provider\deployment_manifest.json");
|
||||||
IsInstalled = File.Exists(installedExe) || File.Exists(pluginManifest);
|
IsInstalled = File.Exists(installedExe) || File.Exists(pluginManifest);
|
||||||
InstalledVersion = "0.1.0";
|
// Пока манифест не прочитан, версия НЕ известна. Раньше здесь стояли
|
||||||
InstalledDate = "19.08.2026";
|
// зашитые "0.1.0" и "19.08.2026", и при нечитаемом манифесте мастер
|
||||||
|
// показывал их как установленную версию — владелец видел «старую
|
||||||
|
// версию» на свежей установке.
|
||||||
|
InstalledVersion = "не определена";
|
||||||
|
InstalledDate = "дата неизвестна";
|
||||||
|
|
||||||
if (File.Exists(pluginManifest))
|
if (File.Exists(pluginManifest))
|
||||||
{
|
{
|
||||||
|
|
@ -336,9 +344,14 @@ namespace HermesHubSetup
|
||||||
"{{\n \"version\": \"{0}\",\n \"deployed_at\": \"{1}\",\n \"git_commit\": \"{2}\"\n}}",
|
"{{\n \"version\": \"{0}\",\n \"deployed_at\": \"{1}\",\n \"git_commit\": \"{2}\"\n}}",
|
||||||
HUB_VERSION,
|
HUB_VERSION,
|
||||||
DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:ssZ"),
|
DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:ssZ"),
|
||||||
"8cddc9f"
|
BuildCommit
|
||||||
);
|
);
|
||||||
File.WriteAllText(manifestFile, manifestJson, Encoding.UTF8);
|
// Запись через временный файл: прерванная запись оставляла
|
||||||
|
// пустой манифест, и разбор версии падал на первом символе.
|
||||||
|
string manifestTmp = manifestFile + ".tmp";
|
||||||
|
File.WriteAllText(manifestTmp, manifestJson, Encoding.UTF8);
|
||||||
|
if (File.Exists(manifestFile)) File.Delete(manifestFile);
|
||||||
|
File.Move(manifestTmp, manifestFile);
|
||||||
}
|
}
|
||||||
catch { }
|
catch { }
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,16 @@ if (Test-Path $HubWebCs) {
|
||||||
# Собираем полезную нагрузку: всё, что нужно PerformInstall на целевой машине.
|
# Собираем полезную нагрузку: всё, что нужно PerformInstall на целевой машине.
|
||||||
# Она вшивается в exe ресурсом, чтобы установщик был одним файлом и не требовал
|
# Она вшивается в exe ресурсом, чтобы установщик был одним файлом и не требовал
|
||||||
# копировать репозиторий.
|
# копировать репозиторий.
|
||||||
|
# Проставляем фактический коммит в исходник установщика, чтобы манифест
|
||||||
|
# развёртывания не сообщал неправду о происхождении сборки.
|
||||||
|
$GitSha = (git -C $RepoRoot rev-parse --short HEAD 2>$null)
|
||||||
|
if ($GitSha) {
|
||||||
|
$csText = Get-Content $SourceFile -Raw -Encoding UTF8
|
||||||
|
$csText = [regex]::Replace($csText, 'public const string BuildCommit = "[^"]*";', "public const string BuildCommit = `"$GitSha`";")
|
||||||
|
Set-Content $SourceFile -Value $csText -Encoding UTF8 -NoNewline
|
||||||
|
Write-Host "Build commit: $GitSha" -ForegroundColor Gray
|
||||||
|
}
|
||||||
|
|
||||||
Write-Host "Packing payload..." -ForegroundColor Cyan
|
Write-Host "Packing payload..." -ForegroundColor Cyan
|
||||||
$PayloadDir = Join-Path $env:TEMP ("hubpayload_" + [guid]::NewGuid().ToString("N").Substring(0,8))
|
$PayloadDir = Join-Path $env:TEMP ("hubpayload_" + [guid]::NewGuid().ToString("N").Substring(0,8))
|
||||||
New-Item -ItemType Directory -Force $PayloadDir | Out-Null
|
New-Item -ItemType Directory -Force $PayloadDir | Out-Null
|
||||||
|
|
|
||||||
Binary file not shown.
Binary file not shown.
|
|
@ -48,14 +48,19 @@ HEALTH_URL="http://$HOST:$PORT/api/health"
|
||||||
|
|
||||||
# Function to check server health
|
# Function to check server health
|
||||||
check_health() {
|
check_health() {
|
||||||
|
# sys импортируется здесь, а не внутри except: раньше на УСПЕШНОМ ответе
|
||||||
|
# возникал NameError, его ловил тот же except, и проверка всегда сообщала
|
||||||
|
# об отказе — сервер работал, а лаунчер писал «failed to respond».
|
||||||
"$PYTHON_BIN" -c "
|
"$PYTHON_BIN" -c "
|
||||||
import urllib.request, json
|
import json
|
||||||
|
import sys
|
||||||
|
import urllib.request
|
||||||
|
|
||||||
try:
|
try:
|
||||||
req = urllib.request.urlopen('$HEALTH_URL', timeout=0.8)
|
with urllib.request.urlopen('$HEALTH_URL', timeout=0.8) as resp:
|
||||||
data = json.loads(req.read().decode('utf-8'))
|
data = json.loads(resp.read().decode('utf-8'))
|
||||||
sys.exit(0 if data.get('ok') is True else 1)
|
sys.exit(0 if data.get('ok') is True else 1)
|
||||||
except Exception:
|
except Exception:
|
||||||
import sys
|
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
" >/dev/null 2>&1
|
" >/dev/null 2>&1
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue