Set-StrictMode -Version Latest $ErrorActionPreference = "Stop" $repoRoot = Split-Path -Parent $MyInvocation.MyCommand.Path $windowsDir = Join-Path $repoRoot "windows" $serverDir = Join-Path $repoRoot "server" $windowsProject = Join-Path $windowsDir "NetTool.Client\NetTool.Client.csproj" $windowsPublishOutput = Join-Path $repoRoot "publish\win-x64" $serverPublishOutput = Join-Path $repoRoot "publish\linux-amd64" $serverConfig = Join-Path $serverDir "internal\config\config.go" if (-not (Test-Path -LiteralPath $windowsProject)) { throw "Windows project not found: $windowsProject" } if (-not (Test-Path -LiteralPath $serverDir)) { throw "Server directory not found: $serverDir" } if (-not (Test-Path -LiteralPath $serverConfig)) { throw "Server config not found: $serverConfig" } $windowsProjectXml = [xml](Get-Content -Raw -LiteralPath $windowsProject) $windowsClientVersion = ($windowsProjectXml.Project.PropertyGroup | ForEach-Object { $_.InformationalVersion } | Where-Object { $_ } | Select-Object -First 1) if ([string]::IsNullOrWhiteSpace($windowsClientVersion)) { throw "InformationalVersion not found in: $windowsProject" } $windowsDefaultExe = Join-Path $windowsPublishOutput "NetTool.Client.exe" $windowsVersionedExeName = "NetTool.Client-$windowsClientVersion-win-x64.exe" $windowsVersionedExe = Join-Path $windowsPublishOutput $windowsVersionedExeName $serverConfigText = Get-Content -Raw -LiteralPath $serverConfig $serverVersionMatch = [regex]::Match($serverConfigText, 'const\s+ServerVersion\s*=\s*"([^"]+)"') if (-not $serverVersionMatch.Success) { throw "ServerVersion not found in: $serverConfig" } $serverVersion = $serverVersionMatch.Groups[1].Value $serverLinuxOutputName = "nettool-server-$serverVersion-linux-amd64" $serverLinuxOutput = Join-Path $serverPublishOutput $serverLinuxOutputName Write-Host "[1/2] Publishing Windows client (Release, self-contained win-x64)..." dotnet publish $windowsProject ` -c Release ` -r win-x64 ` --self-contained true ` -p:PublishSingleFile=true ` -p:IncludeNativeLibrariesForSelfExtract=true ` -p:EnableCompressionInSingleFile=true ` -o $windowsPublishOutput if (-not (Test-Path -LiteralPath $windowsDefaultExe)) { throw "Published executable not found: $windowsDefaultExe" } if (Test-Path -LiteralPath $windowsVersionedExe) { Remove-Item -LiteralPath $windowsVersionedExe -Force } Rename-Item -LiteralPath $windowsDefaultExe -NewName $windowsVersionedExeName if (-not (Test-Path -LiteralPath $serverPublishOutput)) { New-Item -ItemType Directory -Path $serverPublishOutput | Out-Null } $previousGoos = $env:GOOS $previousGoarch = $env:GOARCH $previousCgoEnabled = $env:CGO_ENABLED try { Write-Host "[2/2] Building server for Linux amd64..." Set-Location -LiteralPath $serverDir $env:GOOS = "linux" $env:GOARCH = "amd64" $env:CGO_ENABLED = "0" go build -o $serverLinuxOutput ./cmd/nettool-server } finally { $env:GOOS = $previousGoos $env:GOARCH = $previousGoarch $env:CGO_ENABLED = $previousCgoEnabled Set-Location -LiteralPath $repoRoot } Write-Host "Build completed." Write-Host "Windows client output: publish/win-x64/$windowsVersionedExeName" Write-Host "Server Linux output: publish/linux-amd64/$serverLinuxOutputName"