diff --git a/docs/GITEA_AUTO_UPDATE.md b/docs/GITEA_AUTO_UPDATE.md index 4617d91..65a8f78 100644 --- a/docs/GITEA_AUTO_UPDATE.md +++ b/docs/GITEA_AUTO_UPDATE.md @@ -4,7 +4,8 @@ - Релизы собираются **локально** (CI отключён). - Артефакты кладутся в `D:\TTRPG-Release\` (или копируются из `release\` после сборки). -- Публикация на VPS: `powershell -ExecutionPolicy Bypass -File scripts\publish-to-updates.ps1` +- Подготовка релиза: **`D:\TTRPG-Release\prepare-release.cmd`** (версия, git, сборка Win/Linux, копирование в папку). +- Публикация на VPS: **`D:\TTRPG-Release\publish.cmd`** (проверка + `scp`). Копия в репо: `scripts/ttrpg-release/` - **Имена файлов без версии** — версия только в `latest*.yml`. ## Feed URL diff --git a/package.json b/package.json index dc3dc91..2c75e48 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,11 @@ "pack:mac": "npm run build && electron-builder --mac", "pack:win": "npm run build && node scripts/release-win-prep.mjs && electron-builder --win", "pack:linux": "node scripts/release-linux-pack.mjs", - "publish:updates": "powershell -ExecutionPolicy Bypass -File scripts/publish-to-updates.ps1" + "release": "powershell -ExecutionPolicy Bypass -File scripts/ttrpg-release/release.ps1", + "release:all": "powershell -ExecutionPolicy Bypass -File D:/TTRPG-Release/release-all.ps1", + "prepare:release": "powershell -ExecutionPolicy Bypass -File scripts/ttrpg-release/prepare-release.ps1", + "publish:updates": "powershell -ExecutionPolicy Bypass -File scripts/ttrpg-release/publish.ps1", + "release:all": "powershell -ExecutionPolicy Bypass -File scripts/ttrpg-release/release-all.ps1" }, "keywords": [], "author": "", diff --git a/scripts/publish-to-updates.ps1 b/scripts/publish-to-updates.ps1 deleted file mode 100644 index a4a9d43..0000000 --- a/scripts/publish-to-updates.ps1 +++ /dev/null @@ -1,53 +0,0 @@ -# Заливка релиза на https://updates.mailib.ru/ (nginx root: /var/www/updates_mailib_ru) -# Использование: -# 1) Положите артефакты в $LocalDir (или соберите pack:win и скопируйте из release\) -# 2) powershell -ExecutionPolicy Bypass -File scripts\publish-to-updates.ps1 - -$ErrorActionPreference = 'Stop' - -$Key = "$env:USERPROFILE\.ssh\ttrpg_updates_root" -$LocalDir = 'D:\TTRPG-Release' -$SshTarget = 'root@185.173.94.234' -$RemoteDir = '/var/www/updates_mailib_ru' - -if (-not (Test-Path $Key)) { - Write-Error "SSH key not found: $Key" -} -if (-not (Test-Path $LocalDir)) { - Write-Error "Local release folder not found: $LocalDir" -} - -$patterns = @( - 'latest.yml', - 'latest-linux*.yml', - 'latest-mac.yml', - 'TTRPGPlayer-Setup.exe', - 'TTRPGPlayer-Setup.exe.blockmap', - 'TTRPGPlayer-x64.AppImage', - 'TTRPGPlayer-x86_64.AppImage', - 'TTRPGPlayer-arm64.AppImage', - 'TTRPGPlayer-x64.dmg', - 'TTRPGPlayer-arm64.dmg' -) - -$files = @() -foreach ($pat in $patterns) { - $files += Get-ChildItem -Path $LocalDir -Filter $pat -File -ErrorAction SilentlyContinue -} -$files = $files | Sort-Object -Property Name -Unique - -if (-not $files) { - Write-Error "No release files matched in $LocalDir" -} - -Write-Host "Uploading to ${SshTarget}:${RemoteDir}" -foreach ($f in $files) { - Write-Host " -> $($f.Name)" - & scp -i $Key $f.FullName "${SshTarget}:${RemoteDir}/" -} - -& ssh -i $Key $SshTarget "chown -R www-data:www-data $RemoteDir && ls -la $RemoteDir" - -Write-Host '' -Write-Host 'Verify:' -Write-Host ' curl https://updates.mailib.ru/latest.yml' diff --git a/scripts/ttrpg-release/README.txt b/scripts/ttrpg-release/README.txt new file mode 100644 index 0000000..79805d8 --- /dev/null +++ b/scripts/ttrpg-release/README.txt @@ -0,0 +1,2 @@ +Copy publish.ps1, publish.cmd, publish-config.json to D:\TTRPG-Release\ +when updating the release publisher tool. diff --git a/scripts/ttrpg-release/prepare-release.cmd b/scripts/ttrpg-release/prepare-release.cmd new file mode 100644 index 0000000..ff3c0af --- /dev/null +++ b/scripts/ttrpg-release/prepare-release.cmd @@ -0,0 +1,4 @@ +@echo off +cd /d "%~dp0" +powershell -NoProfile -ExecutionPolicy Bypass -File "%~dp0prepare-release.ps1" %* +if errorlevel 1 pause diff --git a/scripts/ttrpg-release/prepare-release.ps1 b/scripts/ttrpg-release/prepare-release.ps1 new file mode 100644 index 0000000..d524f35 --- /dev/null +++ b/scripts/ttrpg-release/prepare-release.ps1 @@ -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 diff --git a/scripts/ttrpg-release/publish-config.json b/scripts/ttrpg-release/publish-config.json new file mode 100644 index 0000000..7bd3235 --- /dev/null +++ b/scripts/ttrpg-release/publish-config.json @@ -0,0 +1,6 @@ +{ + "sshKey": "%USERPROFILE%\\.ssh\\ttrpg_updates_root", + "sshTarget": "root@185.173.94.234", + "remoteDir": "/var/www/updates_mailib_ru", + "feedUrl": "https://updates.mailib.ru/" +} diff --git a/scripts/ttrpg-release/publish.cmd b/scripts/ttrpg-release/publish.cmd new file mode 100644 index 0000000..f2ce3d4 --- /dev/null +++ b/scripts/ttrpg-release/publish.cmd @@ -0,0 +1,4 @@ +@echo off +cd /d "%~dp0" +powershell -NoProfile -ExecutionPolicy Bypass -File "%~dp0publish.ps1" %* +if errorlevel 1 pause diff --git a/scripts/ttrpg-release/publish.ps1 b/scripts/ttrpg-release/publish.ps1 new file mode 100644 index 0000000..7d55331 --- /dev/null +++ b/scripts/ttrpg-release/publish.ps1 @@ -0,0 +1,216 @@ +# Copy of D:\TTRPG-Release\publish.ps1 - keep in sync when updating the release folder tool. + +param( + [switch]$CheckOnly +) + +Set-StrictMode -Version Latest +$ErrorActionPreference = 'Stop' + +$ReleaseDir = $PSScriptRoot +$ConfigPath = Join-Path $ReleaseDir 'publish-config.json' + +function Expand-ConfigPath([string]$value) { + if ($value -match '%([^%]+)%') { + $envName = $Matches[1] + $envVal = [Environment]::GetEnvironmentVariable($envName) + if ($null -ne $envVal) { + return $value.Replace("%$envName%", $envVal) + } + } + return $value +} + +function Write-Title([string]$text) { + Write-Host '' + Write-Host "=== $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 Write-Warn([string]$text) { + Write-Host " [--] $text" -ForegroundColor Yellow +} + +function Get-YmlReferencedFiles([string]$ymlPath) { + $names = [System.Collections.Generic.HashSet[string]]::new([StringComparer]::OrdinalIgnoreCase) + $content = Get-Content -LiteralPath $ymlPath -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()) + } + return @($names) +} + +function Resolve-ReleaseFile([string]$name) { + $direct = Join-Path $ReleaseDir $name + if (Test-Path -LiteralPath $direct) { + return Get-Item -LiteralPath $direct + } + if ($name -match 'x64' -and $name -notmatch 'x86_64') { + $alt = $name -replace 'x64', 'x86_64' + $altPath = Join-Path $ReleaseDir $alt + if (Test-Path -LiteralPath $altPath) { + return Get-Item -LiteralPath $altPath + } + } + if ($name -match 'x86_64') { + $alt = $name -replace 'x86_64', 'x64' + $altPath = Join-Path $ReleaseDir $alt + if (Test-Path -LiteralPath $altPath) { + return Get-Item -LiteralPath $altPath + } + } + return $null +} + +function Add-FileToUploadSet { + param( + [System.Collections.Generic.HashSet[string]]$set, + [System.IO.FileInfo]$file + ) + [void]$set.Add($file.FullName) +} + +Write-Title 'TTRPG Release Publisher' +Write-Host "Release folder: $ReleaseDir" + +if (-not (Test-Path -LiteralPath $ConfigPath)) { + throw "Missing publish-config.json: $ConfigPath" +} + +$config = Get-Content -LiteralPath $ConfigPath -Raw -Encoding UTF8 | ConvertFrom-Json +$sshKey = Expand-ConfigPath $config.sshKey +$sshTarget = [string]$config.sshTarget +$remoteDir = [string]$config.remoteDir +$feedUrl = [string]$config.feedUrl + +if (-not (Test-Path -LiteralPath $sshKey)) { + throw "SSH key not found: $sshKey" +} + +$errors = [System.Collections.Generic.List[string]]::new() +$warnings = [System.Collections.Generic.List[string]]::new() +$uploadFiles = [System.Collections.Generic.HashSet[string]]::new([StringComparer]::OrdinalIgnoreCase) + +Write-Title 'Windows (required)' +$winYml = Join-Path $ReleaseDir 'latest.yml' +if (-not (Test-Path -LiteralPath $winYml)) { + $errors.Add('Missing latest.yml') +} else { + Write-Ok 'latest.yml' + [void]$uploadFiles.Add($winYml) + foreach ($name in (Get-YmlReferencedFiles $winYml)) { + $file = Resolve-ReleaseFile $name + if ($null -eq $file) { + $errors.Add("Windows: missing file $name (from latest.yml)") + } else { + Write-Ok $file.Name + Add-FileToUploadSet $uploadFiles $file + } + } + $blockmap = Resolve-ReleaseFile 'TTRPGPlayer-Setup.exe.blockmap' + if ($null -eq $blockmap) { + $warnings.Add('Missing TTRPGPlayer-Setup.exe.blockmap (recommended)') + } else { + Write-Ok $blockmap.Name + Add-FileToUploadSet $uploadFiles $blockmap + } +} + +Write-Title 'Linux (if latest-linux*.yml present)' +$linuxYmls = Get-ChildItem -LiteralPath $ReleaseDir -Filter 'latest-linux*.yml' -File -ErrorAction SilentlyContinue +if ($linuxYmls.Count -eq 0) { + Write-Warn 'No latest-linux*.yml - skipping Linux' +} else { + foreach ($yml in $linuxYmls) { + Write-Ok $yml.Name + [void]$uploadFiles.Add($yml.FullName) + foreach ($name in (Get-YmlReferencedFiles $yml.FullName)) { + $file = Resolve-ReleaseFile $name + if ($null -eq $file) { + $errors.Add("Linux ($($yml.Name)): missing file $name") + } else { + if ($file.Name -ne $name) { + Write-Warn "$($yml.Name): yml expects $name, disk has $($file.Name) - will upload $($file.Name)" + } else { + Write-Ok "$($yml.Name) -> $name" + } + Add-FileToUploadSet $uploadFiles $file + } + } + } +} + +Write-Title 'macOS (if latest-mac.yml present)' +$macYml = Join-Path $ReleaseDir 'latest-mac.yml' +if (-not (Test-Path -LiteralPath $macYml)) { + Write-Warn 'No latest-mac.yml - skipping macOS' +} else { + Write-Ok 'latest-mac.yml' + [void]$uploadFiles.Add($macYml) + foreach ($name in (Get-YmlReferencedFiles $macYml)) { + $file = Resolve-ReleaseFile $name + if ($null -eq $file) { + $errors.Add("macOS: missing file $name (from latest-mac.yml)") + } else { + Write-Ok $name + Add-FileToUploadSet $uploadFiles $file + } + } +} + +Write-Title 'Summary' +foreach ($w in $warnings) { + Write-Warn $w +} +if ($errors.Count -gt 0) { + foreach ($e in $errors) { + Write-Fail $e + } + Write-Host '' + Write-Host 'Upload cancelled. Fix the release folder and run again.' -ForegroundColor Red + exit 1 +} + +Write-Host '' +Write-Host "Files to upload: $($uploadFiles.Count)" -ForegroundColor Green +foreach ($path in ($uploadFiles | Sort-Object)) { + Write-Host " - $([System.IO.Path]::GetFileName($path))" +} + +if ($CheckOnly) { + Write-Host '' + Write-Host 'CheckOnly: upload skipped.' -ForegroundColor Yellow + exit 0 +} + +Write-Title 'Upload' +Write-Host "Target: ${sshTarget}:${remoteDir}" +Write-Host "Feed: $feedUrl" + +foreach ($path in ($uploadFiles | Sort-Object)) { + $name = [System.IO.Path]::GetFileName($path) + Write-Host " -> $name" + & scp -i $sshKey -q $path "${sshTarget}:${remoteDir}/" + if ($LASTEXITCODE -ne 0) { + throw "scp failed for $name (exit $LASTEXITCODE)" + } +} + +Write-Host '' +Write-Host 'Setting www-data ownership on server...' +& ssh -i $sshKey $sshTarget "chown -R www-data:www-data '$remoteDir'" +if ($LASTEXITCODE -ne 0) { + throw "ssh chown failed (exit $LASTEXITCODE)" +} + +Write-Title 'Done' +Write-Host 'Verify:' +Write-Host " ${feedUrl}latest.yml" +exit 0 diff --git a/scripts/ttrpg-release/release-all.cmd b/scripts/ttrpg-release/release-all.cmd new file mode 100644 index 0000000..b0fe4b2 --- /dev/null +++ b/scripts/ttrpg-release/release-all.cmd @@ -0,0 +1,4 @@ +@echo off +cd /d "%~dp0" +powershell -NoProfile -ExecutionPolicy Bypass -File "%~dp0release-all.ps1" %* +if errorlevel 1 pause diff --git a/scripts/ttrpg-release/release-all.ps1 b/scripts/ttrpg-release/release-all.ps1 new file mode 100644 index 0000000..2e53ae0 --- /dev/null +++ b/scripts/ttrpg-release/release-all.ps1 @@ -0,0 +1,56 @@ +# Copy of D:\TTRPG-Release\release-all.ps1 + +param( + [string]$Version = '', + [switch]$Patch, + [switch]$Minor, + [switch]$SkipGit, + [switch]$SkipLinux, + [switch]$NoBump, + [switch]$CheckOnlyPublish +) + +Set-StrictMode -Version Latest +$ErrorActionPreference = 'Stop' + +$ToolDir = $PSScriptRoot +$PrepareScript = Join-Path $ToolDir 'prepare-release.ps1' +$PublishScript = Join-Path $ToolDir 'publish.ps1' + +if (-not (Test-Path -LiteralPath $PrepareScript)) { + throw "Missing prepare-release.ps1: $PrepareScript" +} +if (-not (Test-Path -LiteralPath $PublishScript)) { + throw "Missing publish.ps1: $PublishScript" +} + +$prepareArgs = @() +if ($Version) { $prepareArgs += '-Version', $Version } +if ($Patch) { $prepareArgs += '-Patch' } +if ($Minor) { $prepareArgs += '-Minor' } +if ($SkipGit) { $prepareArgs += '-SkipGit' } +if ($SkipLinux) { $prepareArgs += '-SkipLinux' } +if ($NoBump) { $prepareArgs += '-NoBump' } + +$publishArgs = @() +if ($CheckOnlyPublish) { $publishArgs += '-CheckOnly' } + +Write-Host '=== TTRPG Full Release ===' -ForegroundColor Cyan +Write-Host '' + +Write-Host '>>> Phase 1/2: Prepare release' -ForegroundColor Yellow +& powershell -NoProfile -ExecutionPolicy Bypass -File $PrepareScript @prepareArgs +if ($LASTEXITCODE -ne 0) { + throw "Prepare release failed (exit $LASTEXITCODE). Publish not started." +} + +Write-Host '' +Write-Host '>>> Phase 2/2: Publish to server' -ForegroundColor Yellow +& powershell -NoProfile -ExecutionPolicy Bypass -File $PublishScript @publishArgs +if ($LASTEXITCODE -ne 0) { + throw "Publish failed (exit $LASTEXITCODE)" +} + +Write-Host '' +Write-Host '=== Full release completed ===' -ForegroundColor Green +exit 0 diff --git a/scripts/ttrpg-release/release-config.json b/scripts/ttrpg-release/release-config.json new file mode 100644 index 0000000..faf0f63 --- /dev/null +++ b/scripts/ttrpg-release/release-config.json @@ -0,0 +1,7 @@ +{ + "projectRoot": "D:\\Work\\my_projects\\dnd_project\\dnd_player", + "releaseDir": "D:\\TTRPG-Release", + "gitRemote": "origin", + "giteaMcpConfig": "C:\\Users\\Administrator\\.cursor\\mcp.json", + "wslDistro": "" +} diff --git a/scripts/ttrpg-release/release.cmd b/scripts/ttrpg-release/release.cmd new file mode 100644 index 0000000..eeef002 --- /dev/null +++ b/scripts/ttrpg-release/release.cmd @@ -0,0 +1,4 @@ +@echo off +cd /d "%~dp0" +powershell -NoProfile -ExecutionPolicy Bypass -File "%~dp0release.ps1" %* +if errorlevel 1 pause diff --git a/scripts/ttrpg-release/release.ps1 b/scripts/ttrpg-release/release.ps1 new file mode 100644 index 0000000..578bccc --- /dev/null +++ b/scripts/ttrpg-release/release.ps1 @@ -0,0 +1,54 @@ +# Full release: prepare (version, git, build, copy) then publish (validate + upload). +# Run: release.cmd + +param( + [string]$Version = '', + [switch]$Minor, + [switch]$SkipGit, + [switch]$SkipLinux, + [switch]$NoBump, + [switch]$CheckOnly +) + +Set-StrictMode -Version Latest +$ErrorActionPreference = 'Stop' + +$ToolDir = $PSScriptRoot +$PrepareScript = Join-Path $ToolDir 'prepare-release.ps1' +$PublishScript = Join-Path $ToolDir 'publish.ps1' + +if (-not (Test-Path -LiteralPath $PrepareScript)) { + throw "Missing prepare-release.ps1 in $ToolDir" +} +if (-not (Test-Path -LiteralPath $PublishScript)) { + throw "Missing publish.ps1 in $ToolDir" +} + +Write-Host '=== TTRPG Full Release ===' -ForegroundColor Cyan +Write-Host 'Step A: prepare-release' +Write-Host 'Step B: publish (after prepare succeeds)' +Write-Host '' + +$prepareArgs = @('-File', $PrepareScript) +if ($Version) { $prepareArgs += '-Version', $Version } +if ($Minor) { $prepareArgs += '-Minor' } +if ($SkipGit) { $prepareArgs += '-SkipGit' } +if ($SkipLinux) { $prepareArgs += '-SkipLinux' } +if ($NoBump) { $prepareArgs += '-NoBump' } + +& powershell -NoProfile -ExecutionPolicy Bypass @prepareArgs +if ($LASTEXITCODE -ne 0) { + Write-Host '' + Write-Host 'Prepare failed. Publish was not started.' -ForegroundColor Red + exit $LASTEXITCODE +} + +Write-Host '' +Write-Host 'Prepare finished. Starting publish...' -ForegroundColor Green +Write-Host '' + +$publishArgs = @('-File', $PublishScript) +if ($CheckOnly) { $publishArgs += '-CheckOnly' } + +& powershell -NoProfile -ExecutionPolicy Bypass @publishArgs +exit $LASTEXITCODE