Files
aego/tools/ci/github-windows-installer-smoke.ps1
sanspie a46347e2c6
ci-platforms / darwin arm64 smoke (push) Skipped
ci / build (amd64, linux, ubuntu-24.04) (push) Failing after 12m19s
ci-platforms / darwin amd64 smoke (push) Skipped
ci-platforms / windows amd64 smoke (push) Skipped
github-native / gitea-pending (push) Skipped
github-native / darwin amd64 native (push) Skipped
github-native / linux amd64 native (push) Skipped
github-native / windows amd64 native (push) Skipped
github-native / darwin arm64 native (push) Skipped
github-native / gitea-result (push) Skipped
ci / checks (push) Failing after 23m57s
ci / release (push) Skipped
GitHub / windows amd64 native GitHub-hosted native CI: failure
GitHub / darwin arm64 native GitHub-hosted native CI: failure
GitHub / darwin amd64 native GitHub-hosted native CI: failure
GitHub / linux amd64 native GitHub-hosted native CI: success
editor: add art studio and stage 12.5 workflows
2026-11-08 18:47:57 +03:00

128 lines
8.3 KiB
PowerShell

$ErrorActionPreference = 'Stop'
# The installer kills processes by executable name and changes HKCU. Never run
# it on a developer machine or a self-hosted runner.
if ($env:GITHUB_ACTIONS -ne 'true' -or $env:RUNNER_ENVIRONMENT -ne 'github-hosted' -or
$env:GITHUB_SERVER_URL -ne 'https://github.com') {
throw 'Installer smoke is restricted to an ephemeral GitHub-hosted runner.'
}
if (Get-Process aego-editor -ErrorAction SilentlyContinue) { throw 'An editor is already running.' }
$install = Join-Path $env:RUNNER_TEMP 'aego-ci-install'
if ($install.Contains(' ')) { throw 'NSIS /D requires an unquoted install path; runner temp contains spaces.' }
$registry = @(
'HKCU:\Software\Aego',
'HKCU:\Software\Microsoft\Windows\CurrentVersion\Uninstall\Aego',
'HKCU:\Software\Classes\Aego.Project',
'HKCU:\Software\Classes\Aego.Scene',
'HKCU:\Software\Classes\Aego.Prefab',
'HKCU:\Software\Classes\Directory\shell\Aego',
'HKCU:\Software\Classes\Directory\Background\shell\Aego',
'HKCU:\Software\Classes\.aego',
'HKCU:\Software\Classes\.aescene',
'HKCU:\Software\Classes\.aeprefab'
)
foreach ($key in $registry) { if (Test-Path $key) { throw "Refusing to overwrite existing key: $key" } }
$startMenu = Join-Path ([Environment]::GetFolderPath('Programs')) 'Aego'
$desktop = Join-Path ([Environment]::GetFolderPath('Desktop')) 'Aego.lnk'
if ((Test-Path $install) -or (Test-Path $startMenu) -or (Test-Path $desktop)) {
throw 'Install directory or shortcuts already exist.'
}
$beforePath = [Environment]::GetEnvironmentVariable('Path', 'User')
$envKey = [Microsoft.Win32.Registry]::CurrentUser.CreateSubKey('Environment', $true)
$rawPresent = @($envKey.GetValueNames()) -icontains 'Path'
$rawBefore = if ($rawPresent) { [string]$envKey.GetValue('Path', '', [Microsoft.Win32.RegistryValueOptions]::DoNotExpandEnvironmentNames) } else { '' }
$rawKind = if ($rawPresent) { $envKey.GetValueKind('Path') } else { [Microsoft.Win32.RegistryValueKind]::ExpandString }
$pathScript = Join-Path $env:GITHUB_WORKSPACE 'tools\release\windows\path.ps1'
$testDir = Join-Path $env:RUNNER_TEMP "aego-path-test's"
try {
# The runner is ephemeral. Exercise the actual registry adapter before the
# installer, including empty segments, external edits and an existing entry.
$fixture = 'C:\Tools;;%LOCALAPPDATA%\Example;'
$envKey.SetValue('Path', $fixture, [Microsoft.Win32.RegistryValueKind]::ExpandString)
& $pathScript -Action Install -Directory $testDir
$added = [string]$envKey.GetValue('Path', '', [Microsoft.Win32.RegistryValueOptions]::DoNotExpandEnvironmentNames)
if ($added -cne "$fixture;$testDir") { throw 'PATH installation changed existing segments.' }
$envKey.SetValue('Path', "$added;C:\AddedLater;;", [Microsoft.Win32.RegistryValueKind]::ExpandString)
& $pathScript -Action Uninstall -Directory $testDir
$after = [string]$envKey.GetValue('Path', '', [Microsoft.Win32.RegistryValueOptions]::DoNotExpandEnvironmentNames)
if ($after -cne "$fixture;C:\AddedLater;;" -or $envKey.GetValueKind('Path') -ne [Microsoft.Win32.RegistryValueKind]::ExpandString) {
throw 'PATH uninstall changed unrelated entries or its registry type.'
}
$preexisting = "C:\Tools;$testDir;"
$envKey.SetValue('Path', $preexisting, [Microsoft.Win32.RegistryValueKind]::String)
& $pathScript -Action Install -Directory $testDir
& $pathScript -Action Uninstall -Directory $testDir
$after = [string]$envKey.GetValue('Path', '', [Microsoft.Win32.RegistryValueOptions]::DoNotExpandEnvironmentNames)
if ($after -cne $preexisting -or $envKey.GetValueKind('Path') -ne [Microsoft.Win32.RegistryValueKind]::String) {
throw 'Uninstall changed a pre-existing user PATH entry.'
}
$envKey.DeleteValue('Path', $false)
& $pathScript -Action Install -Directory $testDir
& $pathScript -Action Uninstall -Directory $testDir
if (@($envKey.GetValueNames()) -icontains 'Path') { throw 'An originally absent PATH was recreated.' }
} finally {
if ($rawPresent) { $envKey.SetValue('Path', $rawBefore, $rawKind) } else { $envKey.DeleteValue('Path', $false) }
$envKey.Dispose()
# The safety check above established that this key did not exist. Refuse
# recursive deletion if anything unexpected was created under it.
[Microsoft.Win32.Registry]::CurrentUser.DeleteSubKey('Software\Aego', $false)
}
$workspace = $env:GITHUB_WORKSPACE
$portableZip = Join-Path $workspace '.cache\github-ci\dist\portable\aego-windows-amd64-portable.zip'
$portableDir = Join-Path $env:RUNNER_TEMP 'aego-ci-portable'
if (Test-Path $portableDir) { throw 'Portable smoke directory already exists.' }
Expand-Archive -Path $portableZip -DestinationPath $portableDir
foreach ($file in @('aego.exe', 'aego-editor.exe', 'VERSION', 'README.txt')) {
if (-not (Test-Path (Join-Path $portableDir $file) -PathType Leaf)) { throw "Missing portable $file" }
}
$previousProcessPath = $env:Path
try {
$env:Path = "$env:SystemRoot\System32;$env:SystemRoot"
& (Join-Path $portableDir 'aego.exe') version
if ($LASTEXITCODE -ne 0) { throw 'Portable CLI did not start with system-only PATH.' }
} finally { $env:Path = $previousProcessPath }
$setup = Join-Path $workspace '.cache\github-ci\dist\installer\aego-windows-amd64-setup.exe'
$proc = Start-Process -FilePath $setup -ArgumentList @('/S', "/D=$install") -Wait -PassThru
if ($proc.ExitCode -ne 0) { throw "Installer returned $($proc.ExitCode)" }
foreach ($file in @('aego.exe', 'aego-editor.exe', 'VERSION', 'README.txt', 'aego-path.ps1', 'setup.exe', 'uninstall.exe')) {
if (-not (Test-Path (Join-Path $install $file) -PathType Leaf)) { throw "Missing installed $file" }
}
foreach ($shortcut in @((Join-Path $startMenu 'Aego.lnk'), (Join-Path $startMenu 'Uninstall Aego.lnk'), $desktop)) {
if (-not (Test-Path $shortcut -PathType Leaf)) { throw "Missing shortcut: $shortcut" }
}
$shell = New-Object -ComObject WScript.Shell
if ($shell.CreateShortcut((Join-Path $startMenu 'Aego.lnk')).TargetPath -ne (Join-Path $install 'aego-editor.exe') -or
$shell.CreateShortcut((Join-Path $startMenu 'Uninstall Aego.lnk')).TargetPath -ne (Join-Path $install 'uninstall.exe') -or
$shell.CreateShortcut($desktop).TargetPath -ne (Join-Path $install 'aego-editor.exe')) {
throw 'A shortcut targets the wrong executable.'
}
foreach ($association in @(@('.aego', 'Aego.Project'), @('.aescene', 'Aego.Scene'), @('.aeprefab', 'Aego.Prefab'))) {
$actual = (Get-Item ("HKCU:\Software\Classes\" + $association[0])).GetValue('')
if ($actual -ne $association[1]) { throw "Incorrect file association for $($association[0])" }
}
if (([Environment]::GetEnvironmentVariable('Path', 'User') -split ';') -notcontains $install) {
throw 'Installer did not add install directory to user PATH.'
}
$previousProcessPath = $env:Path
try {
$env:Path = "$env:SystemRoot\System32;$env:SystemRoot"
& (Join-Path $install 'aego.exe') version
if ($LASTEXITCODE -ne 0) { throw 'Installed CLI did not start with system-only PATH.' }
} finally { $env:Path = $previousProcessPath }
& (Join-Path $install 'aego.exe') run (Join-Path $workspace '.cache\github-ci\project') --headless --frames 60
if ($LASTEXITCODE -ne 0) { throw 'Installed headless runtime failed.' }
$userData = Join-Path $install 'user-data'
New-Item -ItemType Directory -Path $userData | Out-Null
Set-Content -Path (Join-Path $userData 'keep.txt') -Value 'keep user data'
$proc = Start-Process -FilePath (Join-Path $install 'uninstall.exe') -ArgumentList '/S' -Wait -PassThru
if ($proc.ExitCode -ne 0) { throw "Uninstaller returned $($proc.ExitCode)" }
for ($i = 0; $i -lt 30 -and (Test-Path (Join-Path $install 'uninstall.exe')); $i++) { Start-Sleep -Seconds 1 }
foreach ($file in @('aego.exe', 'aego-editor.exe', 'VERSION', 'README.txt', 'aego-path.ps1', 'setup.exe', 'uninstall.exe')) {
if (Test-Path (Join-Path $install $file)) { throw "Uninstaller left $file" }
}
if (-not (Test-Path (Join-Path $userData 'keep.txt'))) { throw 'Uninstaller removed user data.' }
foreach ($shortcut in @($startMenu, $desktop)) { if (Test-Path $shortcut) { throw "Uninstaller left $shortcut" } }
foreach ($key in $registry) { if (Test-Path $key) { throw "Uninstaller left $key" } }
if ([Environment]::GetEnvironmentVariable('Path', 'User') -ne $beforePath) { throw 'User PATH was not restored.' }
Write-Host 'Silent install/uninstall smoke passed. No GUI interaction or signature validation was performed.'