82 lines
6.4 KiB
PowerShell
82 lines
6.4 KiB
PowerShell
param([switch]$ResumeAndroidSmoke)
|
|
$ErrorActionPreference = 'Stop'
|
|
$projectRoot = 'C:/git/MagnetismHeroes'
|
|
Set-Location -LiteralPath $projectRoot
|
|
$env:PATH = 'C:/Users/baram/AppData/Local/Unity/bin;' + $env:PATH
|
|
$evidence = Join-Path $projectRoot 'artifacts/verification/VisualUpgrade/FinalProduct'
|
|
New-Item -ItemType Directory -Path $evidence -Force | Out-Null
|
|
$sourceCommit = (& git rev-parse HEAD).Trim()
|
|
if ([bool](& git status --porcelain)) { throw 'Final source must be clean.' }
|
|
$productPaths = @(& git ls-files Assets Packages ProjectSettings tools)
|
|
$before = [ordered]@{}
|
|
foreach ($path in $productPaths) { $before[$path] = (Get-FileHash -LiteralPath $path -Algorithm SHA256).Hash }
|
|
$beforePath = Join-Path $evidence 'product-before.json'
|
|
if ($ResumeAndroidSmoke) {
|
|
$originalBefore = Get-Content -LiteralPath $beforePath -Raw | ConvertFrom-Json -AsHashtable
|
|
if (@($productPaths | Where-Object { $originalBefore[$_] -ne $before[$_] }).Count -ne 0) { throw 'Product source differs from the original final-check source.' }
|
|
} else { $before | ConvertTo-Json -Depth 4 | Set-Content -LiteralPath $beforePath -Encoding utf8 }
|
|
$env:MAGNETISM_VISUAL_EVIDENCE = Join-Path $evidence 'EditorCapture'
|
|
$env:MAGNETISM_PROOF_COMMIT = $sourceCommit
|
|
$env:MAGNETISM_PROOF_DIRTY = 'false'
|
|
$record = [ordered]@{sourceCommit=$sourceCommit;startedUtc=[DateTime]::UtcNow.ToString('o');status='running';phases=@();productFiles=$productPaths.Count}
|
|
$recordPath = Join-Path $evidence 'completion.json'
|
|
$phases = @('EditMode','PlayMode','AndroidBuild','AndroidSmoke')
|
|
function Confirm-AndroidReadiness {
|
|
$sdkAdb = Join-Path $env:LOCALAPPDATA 'Android/Sdk/platform-tools/adb.exe'
|
|
$readiness = [ordered]@{startedUtc=[DateTime]::UtcNow.ToString('o');serial='emulator-5554';adb=$sdkAdb;commands=@();status='running'}
|
|
foreach ($arguments in @(@('kill-server'), @('start-server'), @('-s','emulator-5554','get-state'), @('-s','emulator-5554','shell','getprop','sys.boot_completed'))) {
|
|
$step = $readiness.commands.Count
|
|
$stdout = Join-Path $evidence "adb-readiness-$step.stdout.log"
|
|
$stderr = Join-Path $evidence "adb-readiness-$step.stderr.log"
|
|
$client = Start-Process -FilePath $sdkAdb -ArgumentList $arguments -WindowStyle Hidden -PassThru -RedirectStandardOutput $stdout -RedirectStandardError $stderr
|
|
if (-not $client.WaitForExit(30000)) { Stop-Process -Id $client.Id; throw "ADB readiness command timed out: $arguments" }
|
|
$client.Refresh()
|
|
$output = (Get-Content -LiteralPath $stdout -Raw -ErrorAction SilentlyContinue)
|
|
$readiness.commands += [ordered]@{arguments=$arguments;exitCode=$client.ExitCode;stdout=$stdout;stderr=$stderr;output=$output}
|
|
$readiness | ConvertTo-Json -Depth 6 | Set-Content -LiteralPath (Join-Path $evidence 'android-readiness.json') -Encoding utf8
|
|
if ($client.ExitCode -ne 0) { throw "ADB readiness command failed: $arguments" }
|
|
if ($step -eq 2 -and $output.Trim() -ne 'device') { throw 'Dedicated AVD is not online.' }
|
|
if ($step -eq 3 -and $output.Trim() -ne '1') { throw 'Dedicated AVD has not completed boot.' }
|
|
}
|
|
$readiness.status = 'passed'
|
|
$readiness.finishedUtc = [DateTime]::UtcNow.ToString('o')
|
|
$readiness | ConvertTo-Json -Depth 6 | Set-Content -LiteralPath (Join-Path $evidence 'android-readiness.json') -Encoding utf8
|
|
}
|
|
if ($ResumeAndroidSmoke) {
|
|
$previous = Get-Content -LiteralPath $recordPath -Raw | ConvertFrom-Json -AsHashtable
|
|
$passed = @($previous.phases | Where-Object { $_.phase -ne 'AndroidSmoke' })
|
|
if ($previous.sourceCommit -ne $sourceCommit -or $passed.Count -ne 3 -or @($passed | Where-Object { $_.exitCode -ne 0 -or $_.status -ne 'passed' }).Count -ne 0) { throw 'Cannot resume without three successful phases on this source.' }
|
|
$record.startedUtc = $previous.startedUtc
|
|
$record.resumedUtc = [DateTime]::UtcNow.ToString('o')
|
|
$record.phases = $passed
|
|
$record.failedAttempts = @($previous.phases | Where-Object { $_.phase -eq 'AndroidSmoke' })
|
|
$phases = @('AndroidSmoke')
|
|
}
|
|
try {
|
|
foreach ($phase in $phases) {
|
|
if ($phase -eq 'AndroidSmoke') { Confirm-AndroidReadiness }
|
|
$outerLog = Join-Path $evidence ($phase.ToLowerInvariant() + '-outer.log')
|
|
$started = [DateTime]::UtcNow.ToString('o')
|
|
Write-Output "Starting $phase at $started"
|
|
& pwsh -NoProfile -File tools/verify.ps1 -Phase $phase -Milestone Final *> $outerLog
|
|
$actualExit = $LASTEXITCODE
|
|
$phaseRecordPath = Join-Path $projectRoot ('artifacts/verification/Final/' + $phase.ToLowerInvariant() + '-evidence.json')
|
|
$phaseRecord = Get-Content -LiteralPath $phaseRecordPath -Raw | ConvertFrom-Json
|
|
$record.phases += [ordered]@{phase=$phase;command="pwsh -NoProfile -File tools/verify.ps1 -Phase $phase -Milestone Final";startedUtc=$started;finishedUtc=[DateTime]::UtcNow.ToString('o');exitCode=$actualExit;status=$phaseRecord.status;sourceCommit=$phaseRecord.sourceCommit;sourceDirty=$phaseRecord.sourceDirty;sourceDirtyEnd=$phaseRecord.sourceDirtyEnd;outerLog=$outerLog;evidence=$phaseRecordPath}
|
|
$record | ConvertTo-Json -Depth 8 | Set-Content -LiteralPath $recordPath -Encoding utf8
|
|
if ($actualExit -ne 0 -or $phaseRecord.status -ne 'passed' -or $phaseRecord.sourceCommit -ne $sourceCommit -or $phaseRecord.sourceDirty -or $phaseRecord.sourceDirtyEnd) { throw "$phase failed. See $outerLog" }
|
|
Write-Output "$phase exit $actualExit, status $($phaseRecord.status)"
|
|
}
|
|
$after = [ordered]@{}
|
|
foreach ($path in $productPaths) { $after[$path] = (Get-FileHash -LiteralPath $path -Algorithm SHA256).Hash }
|
|
$after | ConvertTo-Json -Depth 4 | Set-Content -LiteralPath (Join-Path $evidence 'product-after.json') -Encoding utf8
|
|
$changed = @($productPaths | Where-Object { $before[$_] -ne $after[$_] })
|
|
$record.productHashesUnchanged = $changed.Count -eq 0
|
|
$record.changedProducts = $changed
|
|
if ($changed.Count -ne 0 -or [bool](& git status --porcelain) -or (& git rev-parse HEAD).Trim() -ne $sourceCommit) { throw 'Product source changed during final checks.' }
|
|
$record.status = 'passed'
|
|
} catch { $record.status='failed'; $record.error=$_.Exception.Message; Write-Output $record.error }
|
|
finally { $record.finishedUtc=[DateTime]::UtcNow.ToString('o'); $record | ConvertTo-Json -Depth 8 | Set-Content -LiteralPath $recordPath -Encoding utf8 }
|
|
if ($record.status -ne 'passed') { exit 1 }
|
|
Write-Output 'All four final phases passed on the same clean integrated product source.'
|