фикс
This commit is contained in:
@@ -0,0 +1,286 @@
|
||||
# Prepare TTRPG release: bump version, git push, build Win/Linux, copy to release folder.
|
||||
# Run: prepare-release.cmd
|
||||
# Options:
|
||||
# -Version 1.0.17 explicit version (skip auto bump)
|
||||
# -Patch bump patch (default)
|
||||
# -Minor bump minor
|
||||
# -SkipGit skip commit/push
|
||||
# -SkipLinux skip Linux build (WSL)
|
||||
# -NoBump do not change package.json version
|
||||
|
||||
param(
|
||||
[string]$Version = '',
|
||||
[switch]$Patch,
|
||||
[switch]$Minor,
|
||||
[switch]$SkipGit,
|
||||
[switch]$SkipLinux,
|
||||
[switch]$NoBump
|
||||
)
|
||||
|
||||
Set-StrictMode -Version Latest
|
||||
$ErrorActionPreference = 'Stop'
|
||||
|
||||
$ToolDir = $PSScriptRoot
|
||||
$ConfigPath = Join-Path $ToolDir 'release-config.json'
|
||||
|
||||
function Write-Step([int]$n, [string]$text) {
|
||||
Write-Host ''
|
||||
Write-Host "----- Step $n : $text -----" -ForegroundColor Cyan
|
||||
}
|
||||
|
||||
function Write-Ok([string]$text) {
|
||||
Write-Host " [OK] $text" -ForegroundColor Green
|
||||
}
|
||||
|
||||
function Write-Fail([string]$text) {
|
||||
Write-Host " [!!] $text" -ForegroundColor Red
|
||||
}
|
||||
|
||||
function Invoke-Npm {
|
||||
param(
|
||||
[string]$Label,
|
||||
[string[]]$NpmArgs,
|
||||
[string]$WorkingDirectory
|
||||
)
|
||||
Write-Host " > $Label"
|
||||
Push-Location $WorkingDirectory
|
||||
try {
|
||||
& npm @NpmArgs
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
throw "$Label failed (exit $LASTEXITCODE)"
|
||||
}
|
||||
} finally {
|
||||
Pop-Location
|
||||
}
|
||||
}
|
||||
|
||||
function Convert-ToWslPath([string]$winPath) {
|
||||
$full = [System.IO.Path]::GetFullPath($winPath)
|
||||
$p = $full -replace '\\', '/'
|
||||
if ($p -match '^([A-Za-z]):(.*)$') {
|
||||
$drive = $Matches[1].ToLower()
|
||||
return "/mnt/$drive$($Matches[2])"
|
||||
}
|
||||
return $p
|
||||
}
|
||||
|
||||
function Read-PackageVersion([string]$packageJsonPath) {
|
||||
$json = Get-Content -LiteralPath $packageJsonPath -Raw -Encoding UTF8 | ConvertFrom-Json
|
||||
return [string]$json.version
|
||||
}
|
||||
|
||||
function Invoke-NpmVersion {
|
||||
param(
|
||||
[string]$ProjectRoot,
|
||||
[string]$Spec
|
||||
)
|
||||
Invoke-Npm "npm version $Spec" @('version', $Spec, '--no-git-tag-version', '--allow-same-version') $ProjectRoot
|
||||
}
|
||||
|
||||
function Get-GiteaPushUrl([string]$mcpConfigPath) {
|
||||
if (-not (Test-Path -LiteralPath $mcpConfigPath)) {
|
||||
return $null
|
||||
}
|
||||
$raw = Get-Content -LiteralPath $mcpConfigPath -Raw -Encoding UTF8 | ConvertFrom-Json
|
||||
$token = $raw.mcpServers.'gitea-mailib'.env.GITEA_ACCESS_TOKEN
|
||||
if (-not $token) {
|
||||
return $null
|
||||
}
|
||||
return "https://ifontosh:${token}@git.mailib.ru/ifontosh/DndGamePlayer.git"
|
||||
}
|
||||
|
||||
function Invoke-Git {
|
||||
param(
|
||||
[string]$ProjectRoot,
|
||||
[string[]]$GitArgs
|
||||
)
|
||||
& git -C $ProjectRoot @GitArgs
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
throw "git $($GitArgs -join ' ') failed (exit $LASTEXITCODE)"
|
||||
}
|
||||
}
|
||||
|
||||
function Push-Git([string]$ProjectRoot, [string]$Remote, [string]$McpConfigPath) {
|
||||
$branch = (git -C $ProjectRoot rev-parse --abbrev-ref HEAD).Trim()
|
||||
Write-Host " > git push $Remote $branch"
|
||||
& git -C $ProjectRoot push $Remote $branch 2>&1 | ForEach-Object { Write-Host $_ }
|
||||
if ($LASTEXITCODE -eq 0) {
|
||||
return
|
||||
}
|
||||
$pushUrl = Get-GiteaPushUrl $McpConfigPath
|
||||
if (-not $pushUrl) {
|
||||
throw "git push failed and no Gitea token in mcp config"
|
||||
}
|
||||
Write-Host " > git push via Gitea token URL"
|
||||
& git -C $ProjectRoot push $pushUrl "HEAD:${branch}" 2>&1 | ForEach-Object { Write-Host $_ }
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
throw "git push failed (exit $LASTEXITCODE)"
|
||||
}
|
||||
}
|
||||
|
||||
function Copy-ReleaseArtifacts {
|
||||
param(
|
||||
[string]$BuildReleaseDir,
|
||||
[string]$TargetDir
|
||||
)
|
||||
|
||||
if (-not (Test-Path -LiteralPath $TargetDir)) {
|
||||
New-Item -ItemType Directory -Path $TargetDir | Out-Null
|
||||
}
|
||||
|
||||
$names = [System.Collections.Generic.HashSet[string]]::new([StringComparer]::OrdinalIgnoreCase)
|
||||
|
||||
$fixed = @(
|
||||
'latest.yml',
|
||||
'TTRPGPlayer-Setup.exe',
|
||||
'TTRPGPlayer-Setup.exe.blockmap'
|
||||
)
|
||||
foreach ($n in $fixed) {
|
||||
[void]$names.Add($n)
|
||||
}
|
||||
|
||||
foreach ($yml in Get-ChildItem -LiteralPath $BuildReleaseDir -Filter 'latest-linux*.yml' -File -ErrorAction SilentlyContinue) {
|
||||
[void]$names.Add($yml.Name)
|
||||
$content = Get-Content -LiteralPath $yml.FullName -Raw -Encoding UTF8
|
||||
foreach ($m in [regex]::Matches($content, '(?m)^(?:\s*-\s*)?(?:url|path):\s*(\S+)\s*$')) {
|
||||
[void]$names.Add($m.Groups[1].Value.Trim())
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($img in Get-ChildItem -LiteralPath $BuildReleaseDir -Filter 'TTRPGPlayer-*.AppImage' -File -ErrorAction SilentlyContinue) {
|
||||
[void]$names.Add($img.Name)
|
||||
}
|
||||
|
||||
$copied = 0
|
||||
foreach ($name in ($names | Sort-Object)) {
|
||||
$src = Join-Path $BuildReleaseDir $name
|
||||
if (-not (Test-Path -LiteralPath $src)) {
|
||||
if ($name -match 'x64' -and $name -notmatch 'x86_64') {
|
||||
$alt = $name -replace 'x64', 'x86_64'
|
||||
$src = Join-Path $BuildReleaseDir $alt
|
||||
}
|
||||
}
|
||||
if (-not (Test-Path -LiteralPath $src)) {
|
||||
Write-Host " [--] skip (not built): $name" -ForegroundColor Yellow
|
||||
continue
|
||||
}
|
||||
$dest = Join-Path $TargetDir ([System.IO.Path]::GetFileName($src))
|
||||
Copy-Item -LiteralPath $src -Destination $dest -Force
|
||||
Write-Ok "copied $([System.IO.Path]::GetFileName($src))"
|
||||
$copied += 1
|
||||
}
|
||||
|
||||
if ($copied -eq 0) {
|
||||
throw 'No release artifacts copied - check build output in project release folder'
|
||||
}
|
||||
}
|
||||
|
||||
if (-not (Test-Path -LiteralPath $ConfigPath)) {
|
||||
throw "Missing release-config.json: $ConfigPath"
|
||||
}
|
||||
|
||||
$config = Get-Content -LiteralPath $ConfigPath -Raw -Encoding UTF8 | ConvertFrom-Json
|
||||
$projectRoot = [System.IO.Path]::GetFullPath([string]$config.projectRoot)
|
||||
$releaseDir = [System.IO.Path]::GetFullPath([string]$config.releaseDir)
|
||||
$gitRemote = [string]$config.gitRemote
|
||||
$mcpConfig = [string]$config.giteaMcpConfig
|
||||
$wslDistro = [string]$config.wslDistro
|
||||
|
||||
$packageJson = Join-Path $projectRoot 'package.json'
|
||||
$buildReleaseDir = Join-Path $projectRoot 'release'
|
||||
|
||||
if (-not (Test-Path -LiteralPath $packageJson)) {
|
||||
throw "package.json not found: $packageJson"
|
||||
}
|
||||
|
||||
Write-Host '=== TTRPG Prepare Release ===' -ForegroundColor Cyan
|
||||
Write-Host "Project: $projectRoot"
|
||||
Write-Host "Release folder: $releaseDir"
|
||||
|
||||
# Step 1 - version
|
||||
Write-Step 1 'Bump version'
|
||||
$currentVersion = Read-PackageVersion $packageJson
|
||||
$newVersion = $currentVersion
|
||||
|
||||
if ($NoBump) {
|
||||
Write-Ok "version unchanged: $currentVersion"
|
||||
$newVersion = $currentVersion
|
||||
} elseif ($Version) {
|
||||
Invoke-NpmVersion $projectRoot $Version.Trim()
|
||||
$newVersion = Read-PackageVersion $packageJson
|
||||
Write-Ok "version set to $newVersion (was $currentVersion)"
|
||||
} elseif ($Minor) {
|
||||
Invoke-NpmVersion $projectRoot 'minor'
|
||||
$newVersion = Read-PackageVersion $packageJson
|
||||
Write-Ok "version $currentVersion -> $newVersion (minor)"
|
||||
} else {
|
||||
Invoke-NpmVersion $projectRoot 'patch'
|
||||
$newVersion = Read-PackageVersion $packageJson
|
||||
Write-Ok "version $currentVersion -> $newVersion (patch)"
|
||||
}
|
||||
|
||||
# Step 2 - git
|
||||
if ($SkipGit) {
|
||||
Write-Step 2 'Git commit and push (skipped)'
|
||||
} else {
|
||||
Write-Step 2 'Git commit and push'
|
||||
Invoke-Git $projectRoot @('add', 'package.json')
|
||||
if (Test-Path -LiteralPath (Join-Path $projectRoot 'package-lock.json')) {
|
||||
Invoke-Git $projectRoot @('add', 'package-lock.json')
|
||||
}
|
||||
$commitMsg = "chore: release v$newVersion"
|
||||
$status = (git -C $projectRoot status --porcelain).Trim()
|
||||
if ($status) {
|
||||
Invoke-Git $projectRoot @('commit', '-m', $commitMsg)
|
||||
Write-Ok "committed: $commitMsg"
|
||||
} else {
|
||||
Write-Ok 'nothing to commit (version may already be committed)'
|
||||
}
|
||||
Push-Git $projectRoot $gitRemote $mcpConfig
|
||||
Write-Ok 'pushed to remote'
|
||||
}
|
||||
|
||||
# Step 3 - Windows build
|
||||
Write-Step 3 'Build Windows (npm ci + pack:win)'
|
||||
Invoke-Npm 'npm ci' @('ci') $projectRoot
|
||||
Invoke-Npm 'npm run pack:win' @('run', 'pack:win') $projectRoot
|
||||
Write-Ok 'Windows build finished'
|
||||
|
||||
# Step 4 - Linux build
|
||||
if ($SkipLinux) {
|
||||
Write-Step 4 'Build Linux (skipped)'
|
||||
} else {
|
||||
Write-Step 4 'Build Linux via WSL (npm ci + pack:linux)'
|
||||
$wslProject = Convert-ToWslPath $projectRoot
|
||||
$wslCmd = "cd '$wslProject' && npm ci && npm run pack:linux"
|
||||
$wslArgs = @()
|
||||
if ($wslDistro) {
|
||||
$wslArgs += '-d', $wslDistro
|
||||
}
|
||||
$wslArgs += '-e', 'bash', '-lc', $wslCmd
|
||||
Write-Host " > wsl $($wslArgs -join ' ')"
|
||||
& wsl @wslArgs
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
throw "WSL Linux build failed (exit $LASTEXITCODE). Install WSL or use -SkipLinux"
|
||||
}
|
||||
Write-Ok 'Linux build finished'
|
||||
}
|
||||
|
||||
# Step 5 - copy
|
||||
Write-Step 5 'Copy artifacts to release folder'
|
||||
if (-not (Test-Path -LiteralPath $buildReleaseDir)) {
|
||||
throw "Build output missing: $buildReleaseDir"
|
||||
}
|
||||
Copy-ReleaseArtifacts $buildReleaseDir $releaseDir
|
||||
Write-Ok "release folder updated: $releaseDir"
|
||||
|
||||
Write-Host ''
|
||||
Write-Host '=== Prepare release done ===' -ForegroundColor Green
|
||||
Write-Host "Version: $newVersion"
|
||||
Write-Host ''
|
||||
Write-Host 'Next steps:' -ForegroundColor Yellow
|
||||
Write-Host ' 1) Copy Mac files (latest-mac.yml, *.dmg) from Mac into release folder if needed'
|
||||
Write-Host ' 2) Run publish.cmd to validate and upload to updates.mailib.ru'
|
||||
Write-Host ''
|
||||
|
||||
exit 0
|
||||
Reference in New Issue
Block a user