hermes-hub/installer/build_installer.ps1
Hermes Team 8f62adb760 feat(installer): самодостаточный exe для Windows
Владелец: «для винды я думаю нужен exe». Справедливо — «склонируй
репозиторий и собери» это не установка.

HermesHubSetup.exe требовал, чтобы рядом лежали src/, launcher/, assets/,
config/ и scripts/: PerformInstall берёт их из sourceRoot. Поэтому одного
файла не хватало, и на целевую машину пришлось бы копировать репозиторий.

Теперь содержимое упаковывается при сборке и вшивается в exe ресурсом
(/resource:payload.zip,payload). Если рядом с exe и уровнем выше
исходников нет, установщик распаковывает вшитое во временный каталог и
работает с ним. Прежнее поведение сохранено: при запуске из репозитория
используются файлы на диске, ресурс не трогается.

Проверено исполнением: exe скопирован в пустой каталог, из него извлечены
assets, config, launcher, scripts, src; src/antigravity_provider и
launcher/HermesHubWeb.exe на месте. Размер 11.78 МБ.

Тест сборки установщика приведён к реальным ссылкам: добавлена
System.IO.Compression.FileSystem, без неё ZipFile не разрешался.

Тесты: 373 passed, ruff чисто.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-24 09:21:08 +07:00

68 lines
3.4 KiB
PowerShell

# Compile HermesHubSetup.exe and package dist release
$CscPath = "C:\Windows\Microsoft.NET\Framework64\v4.0.30319\csc.exe"
if (-not (Test-Path $CscPath)) {
$CscPath = "C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.exe"
}
$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Definition
$RepoRoot = Split-Path -Parent $ScriptDir
$SourceFile = Join-Path $ScriptDir "HermesHubSetup.cs"
$DistDir = Join-Path $RepoRoot "dist"
New-Item -ItemType Directory -Path $DistDir -Force | Out-Null
$OutFile = Join-Path $DistDir "HermesHubSetup.exe"
$LauncherDir = Join-Path $RepoRoot "launcher"
$HubCs = Join-Path $LauncherDir "HermesHub.cs"
$HubWebCs = Join-Path $LauncherDir "HermesHubWeb.cs"
Write-Host "Compiling native launchers..." -ForegroundColor Cyan
if (Test-Path $HubCs) {
$HubExe = Join-Path $LauncherDir "HermesHub.exe"
& $CscPath /target:winexe /out:"$HubExe" /r:System.Windows.Forms.dll /r:System.Drawing.dll "$HubCs"
}
if (Test-Path $HubWebCs) {
$HubWebExe = Join-Path $LauncherDir "HermesHubWeb.exe"
& $CscPath /target:winexe /out:"$HubWebExe" /r:System.Windows.Forms.dll /r:System.Drawing.dll "$HubWebCs"
}
# Собираем полезную нагрузку: всё, что нужно PerformInstall на целевой машине.
# Она вшивается в exe ресурсом, чтобы установщик был одним файлом и не требовал
# копировать репозиторий.
Write-Host "Packing payload..." -ForegroundColor Cyan
$PayloadDir = Join-Path $env:TEMP ("hubpayload_" + [guid]::NewGuid().ToString("N").Substring(0,8))
New-Item -ItemType Directory -Force $PayloadDir | Out-Null
foreach ($item in @("src", "launcher", "assets", "config", "scripts")) {
$srcPath = Join-Path $RepoRoot $item
if (Test-Path $srcPath) {
Copy-Item $srcPath -Destination (Join-Path $PayloadDir $item) -Recurse -Force
}
}
# Каталоги сборки и кеши в дистрибутив не нужны.
Get-ChildItem $PayloadDir -Recurse -Directory -Include "__pycache__", ".venv", "node_modules" -ErrorAction SilentlyContinue |
Remove-Item -Recurse -Force -ErrorAction SilentlyContinue
$PayloadZip = Join-Path $env:TEMP "hub_payload.zip"
if (Test-Path $PayloadZip) { Remove-Item $PayloadZip -Force }
Compress-Archive -Path (Join-Path $PayloadDir "*") -DestinationPath $PayloadZip -CompressionLevel Optimal
$payloadKB = [int]((Get-Item $PayloadZip).Length / 1KB)
Write-Host "Payload packed: $payloadKB KB" -ForegroundColor Gray
Write-Host "Compiling HermesHubSetup.exe..." -ForegroundColor Cyan
& $CscPath /target:winexe /out:"$OutFile" /r:System.Windows.Forms.dll /r:System.Drawing.dll /r:System.IO.Compression.FileSystem.dll /resource:"$PayloadZip",payload "$SourceFile"
if ($LASTEXITCODE -eq 0) {
Write-Host "Installer compiled successfully: $OutFile" -ForegroundColor Green
# Generate SHA256 Checksums
$sha256 = (Get-FileHash -Path $OutFile -Algorithm SHA256).Hash
$checksumContent = "$sha256 HermesHubSetup.exe"
$checksumFile = Join-Path $DistDir "checksums.txt"
Set-Content -Path $checksumFile -Value $checksumContent -Encoding UTF8
Write-Host "Generated checksum: $checksumFile" -ForegroundColor Green
Write-Host "SHA256: $sha256" -ForegroundColor Gray
} else {
Write-Error "Installer compilation FAILED with exit code $LASTEXITCODE"
}
Remove-Item $PayloadDir -Recurse -Force -ErrorAction SilentlyContinue
Remove-Item $PayloadZip -Force -ErrorAction SilentlyContinue