exchanger/tools/export-windows.ps1

93 lines
4.0 KiB
PowerShell

param(
[ValidateSet("Release", "Debug")]
[string]$Configuration = "Release",
[string]$GodotPath = "D:\Applications\Godot\Godot_v4.7.1-stable_mono_win64\Godot_v4.7.1-stable_mono_win64.exe"
)
$ErrorActionPreference = "Stop"
$projectRoot = (Resolve-Path (Join-Path $PSScriptRoot "..")).Path
$stagePath = Join-Path $projectRoot "artifacts\export-staging"
$windowsRoot = Join-Path $projectRoot "artifacts\windows"
$timestamp = Get-Date -Format "yyyyMMdd-HHmmss"
$isRelease = $Configuration -eq "Release"
$presetName = if ($isRelease) { "Windows x64 Release" } else { "Windows x64 Debug" }
$exportFlag = if ($isRelease) { "--export-release" } else { "--export-debug" }
$outputDirectory = Join-Path $windowsRoot "Exchanger-0.6.0-$Configuration-$timestamp"
$outputFileName = if ($isRelease) { "Exchanger.exe" } else { "Exchanger.Debug.exe" }
$outputExe = Join-Path $outputDirectory $outputFileName
function Assert-SafeWorkspacePath([string]$Path, [string]$ExpectedLeaf) {
$absolute = [System.IO.Path]::GetFullPath($Path)
$workspacePrefix = $projectRoot.TrimEnd([System.IO.Path]::DirectorySeparatorChar) + [System.IO.Path]::DirectorySeparatorChar
if (-not $absolute.StartsWith($workspacePrefix, [System.StringComparison]::OrdinalIgnoreCase) -or
(Split-Path $absolute -Leaf) -ne $ExpectedLeaf) {
throw "Unsafe staging path: $absolute"
}
}
if (-not (Test-Path -LiteralPath $GodotPath -PathType Leaf)) {
throw "Godot 4.7.1 Mono was not found: $GodotPath"
}
if ((Split-Path $GodotPath -Leaf) -like "godot-ai*") {
throw "The official Godot Mono executable is required for export."
}
Assert-SafeWorkspacePath $stagePath "export-staging"
if (Test-Path -LiteralPath $stagePath) {
Remove-Item -LiteralPath $stagePath -Recurse -Force
}
New-Item -ItemType Directory -Path $stagePath | Out-Null
New-Item -ItemType Directory -Path $outputDirectory -Force | Out-Null
$exportSucceeded = $false
try {
$excludedDirectories = @(
".git", ".godot", ".agents", ".vscode", "addons", "artifacts",
"docs", "references", "tests", "tools"
)
$robocopyArguments = @($projectRoot, $stagePath, "/E", "/NFL", "/NDL", "/NJH", "/NJS", "/NP", "/XD") +
($excludedDirectories | ForEach-Object { Join-Path $projectRoot $_ })
& robocopy @robocopyArguments | Out-Null
if ($LASTEXITCODE -ge 8) {
throw "Could not prepare the staging copy (robocopy code $LASTEXITCODE)."
}
$stagedProject = Join-Path $stagePath "project.godot"
$projectText = Get-Content -LiteralPath $stagedProject -Raw
$projectText = $projectText -replace '(?m)^GodotxToast=.*\r?\n', ''
$projectText = $projectText -replace '(?m)^_mcp_game_helper=.*\r?\n', ''
$projectText = $projectText -replace '(?ms)\r?\n\[editor_plugins\].*?(?=\r?\n\[)', ''
Set-Content -LiteralPath $stagedProject -Value $projectText -Encoding UTF8
$importProcess = Start-Process -FilePath $GodotPath -WindowStyle Hidden -Wait -PassThru -ArgumentList @(
"--headless", "--path", $stagePath, "--editor", "--quit-after", "30"
)
if ($importProcess.ExitCode -ne 0) {
throw "Godot could not import the production staging project."
}
$exportProcess = Start-Process -FilePath $GodotPath -WindowStyle Hidden -Wait -PassThru -ArgumentList @(
"--headless", "--path", $stagePath, $exportFlag, ('"' + $presetName + '"'), $outputExe
)
if ($exportProcess.ExitCode -ne 0 -or -not (Test-Path -LiteralPath $outputExe)) {
throw "Windows $Configuration export was not created. Check the Godot 4.7.1 Mono export templates."
}
$exportSucceeded = $true
Write-Host "Windows x64 $Configuration export: $outputDirectory"
}
finally {
Assert-SafeWorkspacePath $stagePath "export-staging"
if (Test-Path -LiteralPath $stagePath) {
Remove-Item -LiteralPath $stagePath -Recurse -Force
}
if (-not $exportSucceeded -and (Test-Path -LiteralPath $outputDirectory)) {
Assert-SafeWorkspacePath $outputDirectory (Split-Path $outputDirectory -Leaf)
Remove-Item -LiteralPath $outputDirectory -Recurse -Force
}
}