param( [string]$Target ) $ErrorActionPreference = "Stop" Write-Host "Unity CI Build - Target: $Target" try { # ----------------------------- # Load toolchain config # ----------------------------- $config = Get-Content ".\ci\toolchain.json" | ConvertFrom-Json $unityVersion = $config.unityVersion $unityRoot = $config.windows.unityRoot $hubExe = Join-Path $env:ProgramFiles "Unity Hub\Unity Hub.exe" if (!(Test-Path $hubExe)) { throw "Unity Hub not found at: $hubExe" } # ----------------------------- # CI SAFETY: kill stale licensing / unity processes # ----------------------------- Write-Host "Cleaning up stale Unity/Licensing processes..." Get-Process Unity* -ErrorAction SilentlyContinue | Stop-Process -Force -ErrorAction SilentlyContinue Get-Process LicensingClient* -ErrorAction SilentlyContinue | Stop-Process -Force -ErrorAction SilentlyContinue Get-Process Unity.Licensing* -ErrorAction SilentlyContinue | Stop-Process -Force -ErrorAction SilentlyContinue Start-Sleep -Seconds 2 # ----------------------------- # Ensure Unity is installed # ----------------------------- $unityEditorPath = Join-Path $unityRoot "$unityVersion\Editor\Unity.exe" if (!(Test-Path $unityEditorPath)) { Write-Host "Installing Unity $unityVersion..." & $hubExe -- --headless install ` --version $unityVersion if ($LASTEXITCODE -ne 0) { throw "Failed to install Unity $unityVersion" } if (!(Test-Path $unityEditorPath)) { throw "Unity installation completed but editor not found: $unityEditorPath" } } Write-Host "Unity: $unityVersion" # ----------------------------- # Ensure required modules # ----------------------------- $modules = $config.windows.modules if ($modules.Count -gt 0) { Write-Host "Checking Unity modules..." $installedEditors = & $hubExe -- --headless editors --installed foreach ($module in $modules) { if ($installedEditors -notmatch "$unityVersion.*$module") { Write-Host "Installing module: $module" & $hubExe -- --headless install-modules ` --version $unityVersion ` --module $module if ($LASTEXITCODE -ne 0) { throw "Failed to install module: $module" } } } } # ----------------------------- # Resolve Unity build method # ----------------------------- if ([string]::IsNullOrWhiteSpace($Target)) { throw "No Target provided." } $method = switch ($Target) { "Windows" { "BuildScript.Windows" } "Android" { "BuildScript.Android" } default { throw "Unsupported target: $Target" } } Write-Host "Build Method: $method" # ----------------------------- # Paths (ALL LOGS INTO BUILDS FOLDER) # ----------------------------- $artifactDir = Join-Path $PWD "Builds" New-Item -ItemType Directory -Force -Path $artifactDir | Out-Null $logFile = Join-Path $artifactDir "unity_build.log" $artifactLog = Join-Path $artifactDir "unity_build_last_run.log" # Clean old log if (Test-Path $logFile) { Remove-Item $logFile -Force } # ----------------------------- # Unity Arguments # ----------------------------- $unityArgs = @( "-batchmode" "-nographics" "-quit" "-projectPath", "$PWD" "-executeMethod", "$method" "-logFile", "$logFile" ) Write-Host "Starting Unity build..." # ----------------------------- # Start Unity # ----------------------------- $process = Start-Process ` -FilePath $unityEditorPath ` -ArgumentList $unityArgs ` -NoNewWindow ` -PassThru $process.WaitForExit() # ----------------------------- # Wait for log file creation # ----------------------------- $timeoutSeconds = 60 $elapsed = 0 while (!(Test-Path $logFile) -and $elapsed -lt $timeoutSeconds) { Start-Sleep -Seconds 1 $elapsed++ } if (!(Test-Path $logFile)) { throw "Unity log file was not created at: $logFile" } # ----------------------------- # Wait for file writes to finish # ----------------------------- $previousLength = -1 do { $currentLength = (Get-Item $logFile).Length if ($currentLength -eq $previousLength) { break } $previousLength = $currentLength Start-Sleep -Milliseconds 500 } while ($true) # ----------------------------- # Archive log # ----------------------------- Copy-Item $logFile $artifactLog -Force # ----------------------------- # Build failed # ----------------------------- if ($process.ExitCode -ne 0) { Write-Host "" Write-Host "===== Unity Build Failed =====" Write-Host "Exit Code: $($process.ExitCode)" Write-Host "" Write-Host "===== Last 500 Log Lines =====" Get-Content $logFile -Tail 500 exit $process.ExitCode } # ----------------------------- # Build succeeded # ----------------------------- Write-Host "" Write-Host "===== Build Summary =====" Get-Content $logFile | Select-String ` -Pattern @( "Build completed", "Build succeeded", "Build finished", "Total time" ) | ForEach-Object { Write-Host $_.Line } Write-Host "" Write-Host "===== Last 50 Log Lines =====" Get-Content $logFile -Tail 50 Write-Host "" Write-Host "SUCCESS: $Target" } catch { Write-Error $_.Exception.Message exit 1 } finally { Write-Host "Cleanup complete." }