110 lines
5.4 KiB
PowerShell
110 lines
5.4 KiB
PowerShell
<#
|
||
build-publish-ui.ps1 — локальная сборка Windows-бинаря с UI (Fyne) и публикация в Gitea Packages.
|
||
|
||
Почему локально: Fyne-окно требует cgo + C-компилятор (MinGW/gcc), которых нет в CI.
|
||
CI собирает ТОЛЬКО headless-linux (см. .gitea/workflows/ci.yaml). Windows-бинарь
|
||
с графическим окном собирается на Windows-машине Камиля и публикуется скриптом ниже
|
||
в ту же версию commit-<sha7>, что и CI, с теми же companion-файлами (.version/.sha256),
|
||
чтобы автообновление (U4 checksum, ResolveLatest) работало без изменений.
|
||
|
||
Требования:
|
||
- Go с доступным C-компилятором (CGO_ENABLED=1). WinLibs gcc: см. память
|
||
`mem:toolchain/cgo-winlibs-gcc` — bin нужно добавить в PATH перед запуском.
|
||
- Файл scripts/.gitea-creds (git-ignored, см. ниже) с токенами.
|
||
Формат (по одной `ключ=значение` на строку):
|
||
GITEA_TOKEN=write:packages-токен
|
||
UPDATE_TOKEN=read:package-токен
|
||
GIT_MAIN_URL=http://gitea.hal9000.home
|
||
- Ветка уже запушена в `main` (VERSION = commit-<sha7> от текущего HEAD).
|
||
|
||
Пример:
|
||
powershell -ExecutionPolicy Bypass -File scripts/build-publish-ui.ps1
|
||
#>
|
||
|
||
$ErrorActionPreference = "Stop"
|
||
|
||
$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
|
||
$RepoRoot = Split-Path -Parent $ScriptDir
|
||
$CredsFile = Join-Path $ScriptDir ".gitea-creds"
|
||
$Package = "ratatoskr"
|
||
$Owner = "kamelion"
|
||
$Filename = "ratatoskr-windows-amd64.exe"
|
||
|
||
Set-Location $RepoRoot
|
||
|
||
# --- 0. Проверка C-тулчейна ---
|
||
if ($env:CGO_ENABLED -eq "0") { Write-Error "CGO_ENABLED=0 — нужен C-компилятор (MinGW). Уберите его из env." }
|
||
if (-not (Get-Command gcc -ErrorAction SilentlyContinue)) {
|
||
Write-Host "gcc не найден в PATH. Пример (WinLibs):"
|
||
Write-Host ' $p = "<...>\mingw64\bin"; $env:Path = "$p;$env:Path"'
|
||
Write-Error "C-компилятор gcc не найден."
|
||
}
|
||
Write-Host "[ok] gcc: $((gcc --version | Select-Object -First 1))"
|
||
|
||
# --- 1. Чтение секретов ---
|
||
if (-not (Test-Path $CredsFile)) {
|
||
Write-Error "Нет файла секретов: $CredsFile`nФормат: GITEA_TOKEN=... / UPDATE_TOKEN=... / GIT_MAIN_URL=..."
|
||
}
|
||
$creds = @{}
|
||
Get-Content $CredsFile | ForEach-Object {
|
||
$line = $_.Trim()
|
||
if ($line -and -not $line.StartsWith("#")) {
|
||
$kv = $line.Split("=", 2)
|
||
if ($kv.Count -eq 2) { $creds[$kv[0].Trim()] = $kv[1].Trim() }
|
||
}
|
||
}
|
||
$giteaToken = $creds["GITEA_TOKEN"]
|
||
$updateToken = $creds["UPDATE_TOKEN"]
|
||
$giteaUrl = $creds["GIT_MAIN_URL"]
|
||
if (-not $giteaToken) { Write-Error "В $CredsFile нет GITEA_TOKEN (нужен write:packages)." }
|
||
if (-not $giteaUrl) { Write-Error "В $CredsFile нет GIT_MAIN_URL." }
|
||
|
||
# --- 2. Версия = commit-<sha7> текущего HEAD (совпадает с именованием CI) ---
|
||
$sha = (git rev-parse --short HEAD).Trim()
|
||
if (-not $sha) { Write-Error "git rev-parse --short HEAD не дал хэш." }
|
||
$Version = "commit-$sha"
|
||
Write-Host "[build] VERSION=$Version FILENAME=$Filename"
|
||
|
||
# --- 3. Сборка (cgo + UI) ---
|
||
$env:CGO_ENABLED = "1"
|
||
$out = Join-Path $RepoRoot $Filename
|
||
$ldflags = "-s -w -X main.version=${Version} -X main.updateToken=${updateToken}"
|
||
Write-Host "[build] go build -ldflags=... -o $Filename"
|
||
$goArgs = @("build", "-ldflags=$ldflags", "-o", $out, "./cmd/ratatoskr/")
|
||
go $goArgs
|
||
if ($LASTEXITCODE -ne 0) { Write-Error "go build завершился с кодом $LASTEXITCODE" }
|
||
|
||
# --- 4. Companion-файлы (.version, .sha256) ---
|
||
$sha256Hex = (Get-FileHash -Algorithm SHA256 $out).Hash.ToLower()
|
||
$verFile = "$out.version"
|
||
$sumFile = "$out.sha256"
|
||
Set-Content -Path $verFile -Value $Version -NoNewline -Encoding ascii
|
||
Set-Content -Path $sumFile -Value $sha256Hex -NoNewline -Encoding ascii
|
||
Write-Host "[ok] bin: $out ($([math]::Round((Get-Item $out).Length/1MB,1)) MB)"
|
||
Write-Host "[ok] sha256: $sha256Hex"
|
||
|
||
# --- 5. Публикация в Gitea Packages ---
|
||
$api = "$giteaUrl/api/packages/$Owner/generic/$Package/$Version"
|
||
$files = @($Filename, "$Filename.version", "$Filename.sha256")
|
||
foreach ($f in $files) {
|
||
Write-Host "[put] $api/$f"
|
||
curl.exe -sS -X PUT `
|
||
-H "Authorization: token $giteaToken" `
|
||
-H "Content-Type: application/octet-stream" `
|
||
"$api/$f" `
|
||
--data-binary "@$f"
|
||
if ($LASTEXITCODE -ne 0) { Write-Error "curl PUT $f завершился с кодом $LASTEXITCODE" }
|
||
}
|
||
|
||
# --- 6. Самопроверка: читаем .sha256 обратно и сверяем (контракт U4) ---
|
||
Write-Host "[verify] перечитываю $Filename.sha256 из Gitea..."
|
||
$remoteSum = (curl.exe -sS -H "Authorization: token $giteaToken" "$api/$Filename.sha256").Trim()
|
||
if ($remoteSum -ne $sha256Hex) {
|
||
Write-Error "Проверка не сошлась: remote=$remoteSum local=$sha256Hex"
|
||
}
|
||
$remoteVer = (curl.exe -sS -H "Authorization: token $giteaToken" "$api/$Filename.version").Trim()
|
||
if ($remoteVer -ne $Version) {
|
||
Write-Error "Версия не сошлась: remote=$remoteVer local=$Version"
|
||
}
|
||
Write-Host "[ok] опубликовано и проверено: $Version/$Filename (+.version, +.sha256)"
|