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 } }