# 三端一键打包脚本(PowerShell) # 产物:后端 Linux amd64 + 后端 Windows + 桌面端 Windows NSIS 安装包 # 输出:后端根目录/发版/yyyyMMdd-HHmm/<平台>/ # # 注意:本脚本必须是 UTF-8 无 BOM + PowerShell 5.1 兼容写法。 # 中文目录名「发版」用码位构造(0x53D1 0x7248),避免 PS5.1 按 # ANSI 读取脚本导致字面量变成乱码目录名。 # # 用法:在 nl-game-api-gin 目录下执行 # .\build-all.ps1 # 打全部三端 # .\build-all.ps1 -SkipDesktop # 只打后端两端 # .\build-all.ps1 -SkipLinux -SkipWindows # 只打桌面端 param( [switch]$SkipLinux, # 跳过后端 Linux 二进制 [switch]$SkipWindows, # 跳过后端 Windows 二进制 [switch]$SkipWeb, # 跳过 Web 前端 dist(Nginx 部署用) [switch]$SkipDesktop # 跳过桌面端 NSIS 安装包 ) $ErrorActionPreference = 'Stop' # 路径定位:本脚本位于 nl-game-api-gin/,前端在 ../nl-game $repoRoot = Split-Path -Parent $PSScriptRoot $backendDir = $PSScriptRoot $frontendDir = Join-Path $repoRoot 'nl-game' # 中文目录名「发版」:码位构造,免疫脚本编码问题 $releaseDirName = -join @([char]0x53D1, [char]0x7248) # 输出目录:后端根目录/发版/yyyyMMdd-HHmm(精确到分钟,多次打包不覆盖) $stamp = Get-Date -Format 'yyyyMMdd-HHmm' $outDir = Join-Path $backendDir (Join-Path $releaseDirName $stamp) New-Item -ItemType Directory -Force -Path $outDir | Out-Null Write-Host ("==> Output dir: {0}" -f $outDir) -ForegroundColor Cyan function Write-Section($name) { Write-Host "" Write-Host ("====[{0}]====" -f $name) -ForegroundColor Green } # ---------------------------------------------------------------------- # 1. Backend: Linux amd64 (production, CGO_ENABLED=0 static build) # ---------------------------------------------------------------------- if (-not $SkipLinux) { Write-Section 'Backend Linux amd64' Push-Location $backendDir try { $env:GOOS = 'linux'; $env:GOARCH = 'amd64'; $env:CGO_ENABLED = '0' go build -ldflags="-s -w" -o nl-game-api-gin . Remove-Item Env:\GOOS, Env:\GOARCH, Env:\CGO_ENABLED -ErrorAction SilentlyContinue $dest = Join-Path $outDir 'linux-amd64' New-Item -ItemType Directory -Force -Path $dest | Out-Null Copy-Item 'nl-game-api-gin' -Destination $dest -Force Copy-Item 'config.yaml' -Destination $dest -Force Write-Host (" OK {0}" -f (Join-Path $dest 'nl-game-api-gin')) } finally { Pop-Location } } # ---------------------------------------------------------------------- # 2. Backend: Windows amd64 (local debug) # ---------------------------------------------------------------------- if (-not $SkipWindows) { Write-Section 'Backend Windows amd64' Push-Location $backendDir try { $env:GOOS = 'windows'; $env:GOARCH = 'amd64'; $env:CGO_ENABLED = '0' go build -ldflags="-s -w" -o nl-game-api-gin.exe . Remove-Item Env:\GOOS, Env:\GOARCH, Env:\CGO_ENABLED -ErrorAction SilentlyContinue $dest = Join-Path $outDir 'windows-amd64' New-Item -ItemType Directory -Force -Path $dest | Out-Null Copy-Item 'nl-game-api-gin.exe' -Destination $dest -Force Copy-Item 'config.yaml' -Destination $dest -Force Write-Host (" OK {0}" -f (Join-Path $dest 'nl-game-api-gin.exe')) } finally { Pop-Location } } # ---------------------------------------------------------------------- # 3. Frontend web (for Nginx static hosting, base=./) # ---------------------------------------------------------------------- if (-not $SkipWeb) { Write-Section 'Frontend Web (Nginx dist)' if (-not (Test-Path (Join-Path $frontendDir 'node_modules'))) { Write-Host ' First run: npm install ...' -ForegroundColor Yellow Push-Location $frontendDir try { npm install } finally { Pop-Location } } Push-Location $frontendDir try { # 注意:web 版部署在 Nginx 子路径/根路径都可以用相对 base; # 若部署在域名根路径,建议改为 npm run build(绝对 base)。 npm run build | Out-Null $dest = Join-Path $outDir 'web-dist' if (Test-Path $dest) { Remove-Item -Recurse -Force $dest } Copy-Item 'dist' -Destination $dest -Recurse -Force $n = (Get-ChildItem $dest -Recurse -File | Measure-Object).Count Write-Host (" OK {0} ({1} files)" -f $dest, $n) } finally { Pop-Location } } # ---------------------------------------------------------------------- # 4. Desktop: Windows NSIS installer (for players) # ---------------------------------------------------------------------- if (-not $SkipDesktop) { Write-Section 'Desktop Windows NSIS' if (-not (Test-Path (Join-Path $frontendDir 'node_modules'))) { Write-Host ' First run: npm install ...' -ForegroundColor Yellow Push-Location $frontendDir try { npm install } finally { Pop-Location } } Push-Location $frontendDir try { npm run electron:build | Out-Null $src = Join-Path $frontendDir 'release\PixelArcade-Setup-*.exe' $dest = Join-Path $outDir 'desktop-windows' New-Item -ItemType Directory -Force -Path $dest | Out-Null Get-ChildItem $src | Copy-Item -Destination $dest -Force Get-ChildItem (Join-Path $frontendDir 'release\*.blockmap') -ErrorAction SilentlyContinue | Copy-Item -Destination $dest -Force Get-ChildItem "$dest\PixelArcade-Setup-*.exe" | ForEach-Object { Write-Host (" OK {0}" -f $_.FullName) } } finally { Pop-Location } } # ---------------------------------------------------------------------- # Summary # ---------------------------------------------------------------------- Write-Host "" Write-Section 'DONE' Write-Host ("All artifacts: {0}" -f $outDir) Get-ChildItem -Recurse $outDir -File | Select-Object @{n='Path';e={$_.FullName.Replace($outDir, '.').TrimStart('\')}}, @{n='MB';e={[math]::Round($_.Length/1MB, 2)}}