Files
laude/scripts/release.ps1
AnRil 33e237948e
Some checks failed
CI / Typecheck + Tests (push) Has been cancelled
CI / Build (Windows) (push) Has been cancelled
fix(release): write package.json as UTF-8 without BOM
PS5.1 Get-Content -Raw without -Encoding utf8 reads in CP1251, mangling
non-ASCII like em-dash. Set-Content -Encoding utf8 writes a BOM that
breaks PostCSS / electron-builder reads of package.json.

Use .NET ReadAllText/WriteAllText with UTF8Encoding(false) to guarantee
roundtrip-safe UTF-8 without BOM.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-18 15:25:04 +07:00

174 lines
6.1 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
Локальный релиз: бамп версии -> коммит -> тег -> push -> сборка -> upload в Gitea.
.DESCRIPTION
Single-command release flow.
Каждый релиз публикует артефакты в ТРИ места:
1. Тег vX.Y.Z (исторический архив + changelog)
2. Тег update-channel (фиксированный URL для auto-updater)
3. Bridge-теги, указанные в -BridgeTags (для миграции пользователей со
старых версий, у которых запечён старый publish.url).
После того как все пользователи получили версию с новым (фиксированным)
publish.url, аргумент -BridgeTags можно перестать указывать.
.PARAMETER Bump
Какую часть semver инкрементировать: patch (по умолчанию), minor, major.
.PARAMETER Version
Точная версия (напр. "0.5.1"). Если задана, -Bump игнорируется.
.PARAMETER SkipBuild
Пропустить сборку (если уже собрано вручную, .exe лежит в release/).
.PARAMETER BridgeTags
Список старых тегов, в которые нужно ТАКЖЕ перезалить новые артефакты,
чтобы пользователи на этих версиях нашли апдейт. Например: v0.4.0,v0.5.0.
.PARAMETER DryRun
Показать что произойдёт, ничего не делая.
.EXAMPLE
pwsh scripts/release.ps1 -Bump patch
pwsh scripts/release.ps1 -Version 0.5.1 -BridgeTags v0.4.0,v0.5.0
.NOTES
Требует GITEA_TOKEN с правом write:repository.
Канал 'update-channel' должен существовать на Gitea (создаётся однократно).
#>
param(
[ValidateSet('patch', 'minor', 'major')]
[string]$Bump = 'patch',
[string]$Version,
[switch]$SkipBuild,
[string[]]$BridgeTags = @(),
[switch]$DryRun
)
$ErrorActionPreference = 'Stop'
$repoOwner = 'AnRil'
$repoName = 'laude'
$giteaHost = 'xn--90adajar8af4h.xn--p1ai/git'
$channelTag = 'update-channel'
# --- Pre-flight ----------------------------------------------------------
$root = Resolve-Path (Join-Path $PSScriptRoot '..')
Set-Location $root
if (-not $env:GITEA_TOKEN -and -not $DryRun) {
Write-Error 'GITEA_TOKEN not set.'
exit 1
}
$status = git status --porcelain
if ($status) {
Write-Error "Uncommitted changes. Commit or stash first."
exit 1
}
$branch = git rev-parse --abbrev-ref HEAD
if ($branch -ne 'main') {
Write-Warning "Branch is $branch, not main. Press Enter to continue or Ctrl+C to cancel."
Read-Host
}
# --- Compute next version ------------------------------------------------
$pkg = Get-Content package.json | ConvertFrom-Json
$current = $pkg.version
if ($Version) {
$next = $Version
} else {
$parts = $current.Split('.')
$major = [int]$parts[0]; $minor = [int]$parts[1]; $patch = [int]$parts[2]
switch ($Bump) {
'major' { $major++; $minor = 0; $patch = 0 }
'minor' { $minor++; $patch = 0 }
'patch' { $patch++ }
}
$next = "$major.$minor.$patch"
}
$tag = "v$next"
Write-Host ""
Write-Host "Release plan" -ForegroundColor Cyan
Write-Host " current : v$current"
Write-Host " next : $tag"
Write-Host " publish into : $tag, $channelTag$(if ($BridgeTags) { ', ' + ($BridgeTags -join ', ') })"
Write-Host ""
if ($DryRun) {
Write-Host '(dry run - exiting)' -ForegroundColor Yellow
exit 0
}
# --- Bump package.json --------------------------------------------------
# IMPORTANT: read+write as UTF-8 WITHOUT BOM. PS5.1 defaults will (a) read the
# file as CP1251 and mangle non-ASCII chars like em-dash, and (b) write back
# with a BOM that breaks PostCSS / electron-builder reads of package.json.
Write-Host "Bumping package.json to $next..." -ForegroundColor Cyan
$pkgPath = Join-Path $root 'package.json'
$utf8NoBom = New-Object System.Text.UTF8Encoding $false
$pkgJson = [System.IO.File]::ReadAllText($pkgPath, $utf8NoBom)
$pkgJson = $pkgJson -replace "`"version`":\s*`"$current`"", "`"version`": `"$next`""
[System.IO.File]::WriteAllText($pkgPath, $pkgJson, $utf8NoBom)
git add package.json
git commit -m "chore(release): $tag"
# --- Quality gates ------------------------------------------------------
if (-not $SkipBuild) {
Write-Host "Typecheck..." -ForegroundColor Cyan
npm run typecheck
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
Write-Host "Tests..." -ForegroundColor Cyan
npm run test:run
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
Write-Host "Building installer..." -ForegroundColor Cyan
npm run dist
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
}
# --- Verify artifacts ---------------------------------------------------
$installer = Join-Path 'release' "Exercise-Reminder-Setup-$next.exe"
$blockmap = "$installer.blockmap"
$manifest = Join-Path 'release' 'latest.yml'
foreach ($f in @($installer, $blockmap, $manifest)) {
if (-not (Test-Path $f)) {
Write-Error "Artifact missing: $f"
exit 1
}
}
# --- Tag + push ---------------------------------------------------------
Write-Host "Tagging $tag and pushing..." -ForegroundColor Cyan
git tag -a $tag -m "Release $tag"
git push origin main
git push origin $tag
# --- Upload to all target releases --------------------------------------
$uploadScript = Join-Path $PSScriptRoot 'upload-release-assets.ps1'
$targets = @($tag, $channelTag) + $BridgeTags
foreach ($target in $targets) {
Write-Host ""
Write-Host "==> Uploading $next artifacts into release '$target'" -ForegroundColor Cyan
& powershell -ExecutionPolicy Bypass -File $uploadScript -Tag $target -AssetVersion $next
if ($LASTEXITCODE -ne 0) {
Write-Error "Upload to '$target' failed (exit $LASTEXITCODE)"
exit $LASTEXITCODE
}
}
$releaseUrl = "https://$giteaHost/$repoOwner/$repoName/releases/tag/$tag"
Write-Host ""
Write-Host "Release published" -ForegroundColor Green
Write-Host " $releaseUrl"
Write-Host ""
Write-Host "Auto-updater will pick up the new version within ~1 hour on all installed copies."