Files
MagnetismHeroes/.dryforge/002/execution-support/final-product-checks.ps1
T
2026-10-10 01:27:54 +09:00

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.'