Files
GenAudioBookInfo/scripts/release.ps1
2026-02-23 22:29:32 +03:00

247 lines
11 KiB
PowerShell
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<#
.SYNOPSIS
Полный локальный релиз: сборка + архивы + тег + публикация в Gitea.
.DESCRIPTION
Вызывается из Makefile: make release VERSION=X.Y.Z GIT_TOKEN=xxx
.PARAMETER Version
Версия релиза (например, 2.0.0). Обязательный.
.PARAMETER Token
Gitea API-токен. Если не указан — только локальная сборка.
.PARAMETER AppName
Имя приложения (передаётся из Makefile).
.PARAMETER BuildDir
Директория сборки (передаётся из Makefile).
.PARAMETER GiteaUrl
URL Gitea-сервера.
.PARAMETER GiteaRepo
Репозиторий в формате owner/repo.
.PARAMETER GoVersion
Версия Go (для описания релиза).
#>
param(
[Parameter(Mandatory)][string]$Version,
[string]$Token,
[string]$AppName = "genaudiobookinfo",
[string]$BuildDir = "build",
[string]$GiteaUrl = "https://github.dfv24.com",
[string]$GiteaRepo = "fofanov.dmitry/GenAudioBookInfo",
[string]$GoVersion = "unknown"
)
$ErrorActionPreference = "Stop"
$tag = "v$Version"
# ── Валидация ─────────────────────────────────────────────────────────────────
if ($Version -eq 'dev' -or $Version -eq '') {
Write-Host '!!! VERSION не указана. Использование: make release VERSION=X.Y.Z' -ForegroundColor Red
exit 1
}
$dirty = git status --porcelain
if ($dirty) {
Write-Host '!!! Есть незакоммиченные изменения. Сначала сделайте git commit.' -ForegroundColor Red
git status --short
exit 1
}
# ── Начало ────────────────────────────────────────────────────────────────────
Write-Host ""
Write-Host "══════════════════════════════════════════════" -ForegroundColor Cyan
Write-Host " Создание релиза $tag" -ForegroundColor Cyan
Write-Host "══════════════════════════════════════════════" -ForegroundColor Cyan
Write-Host ""
# ── [1/6] Кросс-компиляция ───────────────────────────────────────────────────
Write-Host ">>> [1/6] Кросс-компиляция для всех платформ..." -ForegroundColor Yellow
$env:GOOS = ''
$env:GOARCH = ''
Remove-Item Env:GOARM, Env:GOMIPS -ErrorAction SilentlyContinue
$ErrorActionPreference = "Continue"
& make build-all VERSION=$Version
$buildExit = $LASTEXITCODE
$ErrorActionPreference = "Stop"
if ($buildExit -ne 0) {
Write-Host "!!! Ошибка компиляции." -ForegroundColor Red
exit 1
}
# ── [2/6] Создание архивов ────────────────────────────────────────────────────
Write-Host ""
Write-Host ">>> [2/6] Создание архивов..." -ForegroundColor Yellow
$archDir = Join-Path $BuildDir "archives"
New-Item -ItemType Directory -Force $archDir | Out-Null
Get-ChildItem $BuildDir -File | Where-Object { $_.Name -ne '.env' } | ForEach-Object {
if ($_.Name -match '\.exe$') {
$arcName = $_.BaseName + '.zip'
Write-Host " $($_.Name) -> $arcName"
Compress-Archive -Path $_.FullName -DestinationPath (Join-Path $archDir $arcName) -Force
}
elseif ($_.Name -match "^$([regex]::Escape($AppName))-") {
$arcName = $_.Name + '.tar.gz'
Write-Host " $($_.Name) -> $arcName"
tar -czf (Join-Path $archDir $arcName) -C $BuildDir $_.Name
}
}
# ── [3/6] SHA256 ──────────────────────────────────────────────────────────────
Write-Host ""
Write-Host ">>> [3/6] Генерация SHA256..." -ForegroundColor Yellow
$checksumFile = Join-Path $archDir "checksums-sha256.txt"
$lines = Get-ChildItem $archDir -File |
Where-Object { $_.Name -ne 'checksums-sha256.txt' } |
Get-FileHash -Algorithm SHA256 |
ForEach-Object { "$($_.Hash.ToLower()) $(Split-Path $_.Path -Leaf)" }
$lines | Out-File -Encoding UTF8 $checksumFile
Write-Host " checksums-sha256.txt создан"
# ── [4/6] Тег ─────────────────────────────────────────────────────────────────
Write-Host ""
Write-Host ">>> [4/6] Создание тега $tag..." -ForegroundColor Yellow
$existingTag = git tag -l $tag
if ($existingTag) {
Write-Host " Тег $tag уже существует, пропускаю создание" -ForegroundColor Gray
} else {
git tag -a $tag -m "Release $tag"
}
$ErrorActionPreference = "Continue"
git push origin $tag 2>&1 | Out-Null
git push origin master 2>&1 | Out-Null
$ErrorActionPreference = "Stop"
# ── Проверка токена ───────────────────────────────────────────────────────────
if (-not $Token) {
Write-Host ""
Write-Host "══════════════════════════════════════════════" -ForegroundColor Yellow
Write-Host " Локальная сборка завершена." -ForegroundColor Yellow
Write-Host " Для загрузки в Gitea укажите GIT_TOKEN:" -ForegroundColor Yellow
Write-Host " make release VERSION=$Version GIT_TOKEN=<токен>" -ForegroundColor Yellow
Write-Host " Архивы: $archDir\" -ForegroundColor Yellow
Write-Host "══════════════════════════════════════════════" -ForegroundColor Yellow
exit 0
}
# ── [5/6] Создание релиза в Gitea ────────────────────────────────────────────
Write-Host ""
Write-Host ">>> [5/6] Создание релиза в Gitea..." -ForegroundColor Yellow
$commit = git rev-parse HEAD
$date = Get-Date -Format 'dd.MM.yyyy HH:mm UTC'
$prevTag = ''
$ErrorActionPreference = "Continue"
try { $prevTag = git describe --tags --abbrev=0 "$tag^" 2>&1 | Where-Object { $_ -is [string] } } catch {}
$ErrorActionPreference = "Stop"
$rawLog = @()
if ($prevTag) {
$rawLog = git log --pretty=format:"%s" "$prevTag..$tag" --no-merges 2>$null
} else {
$rawLog = git log --pretty=format:"%s" --no-merges 2>$null | Select-Object -First 50
}
$features = @()
$fixes = @()
$refactor = @()
$other = @()
($rawLog -split "`n") | Where-Object { $_ } | ForEach-Object {
$low = $_.ToLower()
if ($low -match '^(функция|feat|feature|добавлен|реализован|новое)') { $features += "- $_" }
elseif ($low -match '^(исправлен|fix|bugfix|баг|ошибка)') { $fixes += "- $_" }
elseif ($low -match '^(рефакторинг|refactor|оптимизац|улучшен)') { $refactor += "- $_" }
else { $other += "- $_" }
}
# Формируем тело релиза
$body = "## GenAudioBookInfo $tag`n`n"
if (Test-Path 'RELEASE_NOTES.md') {
$body += (Get-Content 'RELEASE_NOTES.md' -Raw) + "`n`n"
}
if ($features.Count -gt 0) { $body += "### Новые возможности`n" + ($features -join "`n") + "`n`n" }
if ($fixes.Count -gt 0) { $body += "### Исправления`n" + ($fixes -join "`n") + "`n`n" }
if ($refactor.Count -gt 0) { $body += "### Рефакторинг`n" + ($refactor -join "`n") + "`n`n" }
if ($other.Count -gt 0) { $body += "### Прочие изменения`n" + ($other -join "`n") + "`n`n" }
$body += "---`n`n### Информация о сборке`n`n"
$body += "| Параметр | Значение |`n|---|---|`n"
$body += "| Коммит | ``$commit`` |`n"
$body += "| Дата | $date |`n"
$body += "| Go | $GoVersion |`n"
# API: создание релиза
$releaseData = @{
tag_name = $tag
target_commitish = $commit
name = "$AppName $tag"
body = $body
draft = $false
prerelease = $false
} | ConvertTo-Json -Compress -Depth 5
$headers = @{
Authorization = "token $Token"
'Content-Type' = 'application/json'
}
$releaseResp = Invoke-RestMethod -Method Post `
-Uri "$GiteaUrl/api/v1/repos/$GiteaRepo/releases" `
-Headers $headers -Body ([System.Text.Encoding]::UTF8.GetBytes($releaseData)) `
-ErrorAction Stop
$releaseId = $releaseResp.id
Write-Host " Релиз создан: ID=$releaseId"
# ── [6/6] Загрузка файлов ────────────────────────────────────────────────────
Write-Host ""
Write-Host ">>> [6/6] Загрузка файлов..." -ForegroundColor Yellow
$ok = 0
$fail = 0
Get-ChildItem $archDir -File | ForEach-Object {
$fname = $_.Name
$fsize = '{0:N1} MB' -f ($_.Length / 1MB)
Write-Host -NoNewline (" {0,-55} [{1,6}] " -f $fname, $fsize)
try {
$bytes = [System.IO.File]::ReadAllBytes($_.FullName)
$uploadHeaders = @{
Authorization = "token $Token"
'Content-Type' = 'application/octet-stream'
}
Invoke-RestMethod -Method Post `
-Uri "$GiteaUrl/api/v1/repos/$GiteaRepo/releases/$releaseId/assets?name=$fname" `
-Headers $uploadHeaders -Body $bytes -ErrorAction Stop | Out-Null
Write-Host "OK" -ForegroundColor Green
$ok++
} catch {
Write-Host "ОШИБКА: $_" -ForegroundColor Red
$fail++
}
}
# ── Итог ──────────────────────────────────────────────────────────────────────
Write-Host ""
Write-Host "══════════════════════════════════════════════" -ForegroundColor Green
Write-Host " Загружено: $ok | Ошибок: $fail" -ForegroundColor Green
Write-Host " Релиз: $GiteaUrl/$GiteaRepo/releases/tag/$tag" -ForegroundColor Green
Write-Host "══════════════════════════════════════════════" -ForegroundColor Green
if ($fail -gt 0) { exit 1 }