111 lines
6.9 KiB
PowerShell
111 lines
6.9 KiB
PowerShell
#Requires -Version 7.0
|
|
# Default is read-only. Root dispatches -Package only after compiler lease release.
|
|
[CmdletBinding()]
|
|
param([switch]$Package)
|
|
Set-StrictMode -Version Latest
|
|
$ErrorActionPreference = 'Stop'
|
|
$packageMain = [IO.Path]::GetFullPath((Join-Path $PSScriptRoot '..'))
|
|
$packageRepo = Join-Path $PSScriptRoot 'canvas-union-ytr83r-20260911'
|
|
$packageRoot = Join-Path $PSScriptRoot 'native-repair-union-33e30c1-r2'
|
|
$packagePython = 'C:/Users/User/.cache/codex-runtimes/codex-primary-runtime/dependencies/python/python.exe'
|
|
$packageVersion = '0.2.0-preview.canvas-repair.20260912'
|
|
$packageTarget = 'x86_64-pc-windows-gnullvm'
|
|
$packageSource = '33e30c1cd7a6c99513a0ebd02ba68fccbad8f58d'
|
|
$packageUtf8 = [Text.UTF8Encoding]::new($false)
|
|
|
|
function Assert-NoCompiler {
|
|
if (Get-Process cargo,rustc -ErrorAction SilentlyContinue) { throw 'Compiler processes active. Wait for compiler lease release and root dispatch.' }
|
|
}
|
|
function Write-FreshJson([string]$Path, $Value) {
|
|
$bytes = $packageUtf8.GetBytes(($Value | ConvertTo-Json -Depth 30) + "`n")
|
|
$stream = [IO.File]::Open($Path, [IO.FileMode]::CreateNew, [IO.FileAccess]::Write, [IO.FileShare]::Read)
|
|
try { $stream.Write($bytes, 0, $bytes.Length) } finally { $stream.Dispose() }
|
|
}
|
|
function Read-Preflight {
|
|
$raw = @(& $packagePython -I (Join-Path $packageRoot 'preflight.py'))
|
|
if ($LASTEXITCODE -ne 0) { throw 'Exact source/build preflight failed; no packaging metadata invoked.' }
|
|
$record = ($raw -join "`n") | ConvertFrom-Json -AsHashtable
|
|
if ($record.scope -cne 'source-and-build' -or $record.pass_preflight -ne $true) { throw 'Insufficient preflight result.' }
|
|
return $record
|
|
}
|
|
|
|
Assert-NoCompiler
|
|
if (-not $Package) {
|
|
Read-Preflight | ConvertTo-Json -Depth 30
|
|
return
|
|
}
|
|
|
|
# A unique attempt is retained even on failure. Never overwrite a prior attempt.
|
|
$packageAttempt = Join-Path $packageRoot 'attempt'
|
|
if (Test-Path -LiteralPath $packageAttempt) { throw 'Attempt already exists; preserve it and review a fresh output root before retry.' }
|
|
[void][IO.Directory]::CreateDirectory($packageRoot)
|
|
$packageClaim = [IO.File]::Open((Join-Path $packageRoot 'package.claim'), [IO.FileMode]::CreateNew, [IO.FileAccess]::Write, [IO.FileShare]::None)
|
|
$packageStarted = [DateTime]::UtcNow.ToString('o')
|
|
$packageTranscript = $false
|
|
try {
|
|
[void][IO.Directory]::CreateDirectory($packageAttempt)
|
|
Start-Transcript -LiteralPath (Join-Path $packageAttempt 'package-transcript.log') -NoClobber | Out-Null
|
|
$packageTranscript = $true
|
|
$packagePreflight = Read-Preflight
|
|
Write-FreshJson (Join-Path $packageAttempt 'preflight.json') $packagePreflight
|
|
$packageInputs = Join-Path $packageRoot 'package-inputs'
|
|
$packageEvidence = Join-Path $packageRoot 'package-build-evidence.json'
|
|
$packageDist = Join-Path $packageRoot 'dist'
|
|
foreach ($fresh in @($packageInputs, $packageEvidence, $packageDist, (Join-Path $packageRoot 'package-result.json'))) {
|
|
if (Test-Path -LiteralPath $fresh) { throw "Output already exists: $fresh" }
|
|
}
|
|
[void][IO.Directory]::CreateDirectory($packageInputs)
|
|
$packageHashes = [ordered]@{}
|
|
foreach ($name in @('arcadia-studio.exe', 'arcadia-server.exe')) {
|
|
$record = if ($name -eq 'arcadia-studio.exe') { $packagePreflight.binaries[$name] } else { $packagePreflight.server_file }
|
|
$destination = Join-Path $packageInputs $name
|
|
$before = (Get-FileHash -LiteralPath $record.path).Hash.ToLowerInvariant()
|
|
if ($before -cne $record.sha256) { throw "Preflight input changed: $name" }
|
|
[IO.File]::Copy($record.path, $destination, $false)
|
|
$copied = (Get-FileHash -LiteralPath $destination).Hash.ToLowerInvariant()
|
|
$after = (Get-FileHash -LiteralPath $record.path).Hash.ToLowerInvariant()
|
|
if ($before -cne $copied -or $before -cne $after -or (Get-Item -LiteralPath $destination).Length -ne $record.bytes) { throw "Package copy mismatch: $name" }
|
|
$packageHashes[$name] = $copied
|
|
}
|
|
$evidence = [ordered]@{
|
|
source_identity = "Studio: $packageSource, exact 530-file freeze. Server: immutable 321897fd55af9e07afa2c6ebf1e50be49e86f7d9 component; identical core/server trees and workspace manifest, sole Cargo.lock delta is oa-desktop unicode-segmentation edge."
|
|
profile = 'debug; unoptimized Windows development prerelease'
|
|
compiler = $packagePreflight.environment.rustc_version
|
|
target = $packageTarget
|
|
binary_sha256 = $packageHashes
|
|
studio_gate_statuses = $packagePreflight.gate_statuses
|
|
studio_binary_manifest = $packagePreflight.binary_manifest
|
|
input_manifest_sha256 = $packagePreflight.manifest_sha256
|
|
verified_source_commit = $packagePreflight.source_commit
|
|
verified_head = $packagePreflight.head
|
|
server_manifest = $packagePreflight.server_manifest
|
|
server_reuse = $packagePreflight.server_reuse
|
|
native_acceptance = 'Pending actual extracted-package verification; final external validation record will identify completed checks.'
|
|
}
|
|
Write-FreshJson $packageEvidence $evidence
|
|
Assert-NoCompiler
|
|
# Scoped to this invocation; restore process environment even after failure.
|
|
$environmentNames = @('CARGO_HOME','RUSTUP_HOME','PATH','CARGO_BUILD_JOBS','CARGO_INCREMENTAL','CARGO_TARGET_X86_64_PC_WINDOWS_GNULLVM_LINKER','RC','RUSTUP_TOOLCHAIN')
|
|
$savedEnvironment = @{}
|
|
foreach ($name in $environmentNames) { $savedEnvironment[$name] = [Environment]::GetEnvironmentVariable($name, 'Process') }
|
|
try {
|
|
. (Join-Path $PSScriptRoot 'toolchain/env.ps1')
|
|
$packageResult = & (Join-Path $packageRepo 'scripts/package-windows.ps1') -Target $packageTarget -Version $packageVersion -BinaryDirectory $packageInputs -LlvmMinGWRoot (Join-Path $PSScriptRoot 'toolchain/llvm-mingw-20260908-ucrt-x86_64') -BuildEvidence $packageEvidence -Python $packagePython -OutputRoot $packageDist
|
|
} finally {
|
|
foreach ($name in $environmentNames) { [Environment]::SetEnvironmentVariable($name, $savedEnvironment[$name], 'Process') }
|
|
}
|
|
if ($null -eq $packageResult -or -not $packageResult.PSObject.Properties['Archive']) { throw 'Packager did not return a result.' }
|
|
$postflight = Read-Preflight
|
|
Write-FreshJson (Join-Path $packageAttempt 'postflight.json') $postflight
|
|
$result = [ordered]@{started_utc=$packageStarted;completed_utc=[DateTime]::UtcNow.ToString('o');exit=0;source_commit=$packageSource;result=$packageResult}
|
|
Write-FreshJson (Join-Path $packageRoot 'package-result.json') $result
|
|
$result | ConvertTo-Json -Depth 12
|
|
} catch {
|
|
$failure = [ordered]@{started_utc=$packageStarted;completed_utc=[DateTime]::UtcNow.ToString('o');exit=1;error=$_.Exception.Message;details=$_.ToString();script_stack=$_.ScriptStackTrace}
|
|
if ((Test-Path -LiteralPath $packageAttempt) -and -not (Test-Path -LiteralPath (Join-Path $packageAttempt 'failure.json'))) { Write-FreshJson (Join-Path $packageAttempt 'failure.json') $failure }
|
|
throw
|
|
} finally {
|
|
if ($packageTranscript) { Stop-Transcript | Out-Null }
|
|
$packageClaim.Dispose()
|
|
}
|