[CmdletBinding()] param( [string]$Preset = "windows-msvc-default", [string]$Configuration = "Debug", [string]$Target = "PanoPainter", [switch]$ReadinessOnly, [string[]]$PackageKinds = @( "windows-appx", "android-standard-apk", "android-quest-apk", "android-focus-apk", "apple-bundle", "webgl" ) ) $ErrorActionPreference = "Stop" $started = Get-Date $root = (Get-Location).Path function Test-CommandAvailable { param([string]$Name) return [bool](Get-Command $Name -ErrorAction SilentlyContinue) } function New-ArtifactCheck { param( [string]$Name, [string]$Path, [string]$PathType = "Any" ) $exists = if ($PathType -eq "Container") { Test-Path -LiteralPath $Path -PathType Container } elseif ($PathType -eq "Leaf") { Test-Path -LiteralPath $Path -PathType Leaf } else { Test-Path -LiteralPath $Path } [ordered]@{ name = $Name path = $Path pathType = $PathType exists = $exists } } function New-Prerequisite { param( [string]$Name, [bool]$Available, [string]$Detail ) [ordered]@{ name = $Name available = $Available detail = $Detail } } function New-PackageReadiness { param( [string]$Kind, [string]$Status, [string]$Reason, [object[]]$Prerequisites, [object[]]$Artifacts, [string]$ValidationCommand ) [ordered]@{ kind = $Kind status = $Status reason = $Reason debt = "DEBT-0011" validationCommand = $ValidationCommand prerequisites = $Prerequisites artifacts = $Artifacts } } function Get-PackageReadiness { param([string[]]$Kinds) $readiness = @() foreach ($kind in $Kinds) { switch ($kind) { "windows-appx" { $wapproj = Join-Path $root "PanoPainterPackage/PanoPainterPackage.wapproj" $manifest = Join-Path $root "PanoPainterPackage/Package.appxmanifest" $appPackages = Join-Path $root "PanoPainterPackage/AppPackages" $readiness += New-PackageReadiness ` -Kind $kind ` -Status "blocked" ` -Reason "legacy-wapproj-present-but-root-cmake-package-target-missing" ` -ValidationCommand "msbuild PanoPainterPackage/PanoPainterPackage.wapproj /p:Configuration=$Configuration /p:Platform=x64" ` -Prerequisites @( (New-Prerequisite -Name "legacy-wapproj" -Available (Test-Path -LiteralPath $wapproj -PathType Leaf) -Detail $wapproj), (New-Prerequisite -Name "appx-manifest" -Available (Test-Path -LiteralPath $manifest -PathType Leaf) -Detail $manifest), (New-Prerequisite -Name "makeappx" -Available (Test-CommandAvailable "makeappx") -Detail "Windows SDK packaging tool"), (New-Prerequisite -Name "signtool" -Available (Test-CommandAvailable "signtool") -Detail "Windows SDK signing tool"), (New-Prerequisite -Name "root-cmake-package-target" -Available $false -Detail "Not migrated yet") ) ` -Artifacts @( (New-ArtifactCheck -Name "app-packages" -Path $appPackages -PathType "Container") ) } "android-standard-apk" { $gradle = Join-Path $root "android/android/build.gradle" $manifest = Join-Path $root "android/android/src/main/AndroidManifest.xml" $apkDir = Join-Path $root "android/android/build/outputs/apk" $readiness += New-PackageReadiness ` -Kind $kind ` -Status "blocked" ` -Reason "legacy-gradle-package-not-consuming-root-cmake-targets" ` -ValidationCommand "gradle -p android/android assembleDebug" ` -Prerequisites @( (New-Prerequisite -Name "gradle-build" -Available (Test-Path -LiteralPath $gradle -PathType Leaf) -Detail $gradle), (New-Prerequisite -Name "android-manifest" -Available (Test-Path -LiteralPath $manifest -PathType Leaf) -Detail $manifest), (New-Prerequisite -Name "gradle" -Available (Test-CommandAvailable "gradle") -Detail "Android package builder"), (New-Prerequisite -Name "root-cmake-preset" -Available $true -Detail "android-arm64/android-x64"), (New-Prerequisite -Name "root-cmake-package-target" -Available $false -Detail "Not migrated yet") ) ` -Artifacts @( (New-ArtifactCheck -Name "apk-output" -Path $apkDir -PathType "Container") ) } "android-quest-apk" { $gradle = Join-Path $root "android/quest/build.gradle" $manifest = Join-Path $root "android/quest/src/main/AndroidManifest.xml" $apkDir = Join-Path $root "android/quest/build/outputs/apk" $readiness += New-PackageReadiness ` -Kind $kind ` -Status "blocked" ` -Reason "legacy-gradle-package-not-consuming-root-cmake-targets" ` -ValidationCommand "gradle -p android/quest assembleDebug" ` -Prerequisites @( (New-Prerequisite -Name "gradle-build" -Available (Test-Path -LiteralPath $gradle -PathType Leaf) -Detail $gradle), (New-Prerequisite -Name "android-manifest" -Available (Test-Path -LiteralPath $manifest -PathType Leaf) -Detail $manifest), (New-Prerequisite -Name "gradle" -Available (Test-CommandAvailable "gradle") -Detail "Android package builder"), (New-Prerequisite -Name "root-cmake-preset" -Available $true -Detail "android-quest-arm64"), (New-Prerequisite -Name "root-cmake-package-target" -Available $false -Detail "Not migrated yet") ) ` -Artifacts @( (New-ArtifactCheck -Name "apk-output" -Path $apkDir -PathType "Container") ) } "android-focus-apk" { $gradle = Join-Path $root "android/focus/build.gradle" $manifest = Join-Path $root "android/focus/src/main/AndroidManifest.xml" $apkDir = Join-Path $root "android/focus/build/outputs/apk" $readiness += New-PackageReadiness ` -Kind $kind ` -Status "blocked" ` -Reason "legacy-gradle-package-not-consuming-root-cmake-targets" ` -ValidationCommand "gradle -p android/focus assembleDebug" ` -Prerequisites @( (New-Prerequisite -Name "gradle-build" -Available (Test-Path -LiteralPath $gradle -PathType Leaf) -Detail $gradle), (New-Prerequisite -Name "android-manifest" -Available (Test-Path -LiteralPath $manifest -PathType Leaf) -Detail $manifest), (New-Prerequisite -Name "gradle" -Available (Test-CommandAvailable "gradle") -Detail "Android package builder"), (New-Prerequisite -Name "root-cmake-preset" -Available $true -Detail "android-focus-arm64"), (New-Prerequisite -Name "root-cmake-package-target" -Available $false -Detail "Not migrated yet") ) ` -Artifacts @( (New-ArtifactCheck -Name "apk-output" -Path $apkDir -PathType "Container") ) } "apple-bundle" { $xcodeProject = Join-Path $root "PanoPainter.xcodeproj/project.pbxproj" $bundleDir = Join-Path $root "out/package/apple" $readiness += New-PackageReadiness ` -Kind $kind ` -Status "blocked" ` -Reason "legacy-xcode-project-and-host-toolchain-not-aligned-with-root-cmake-package-target" ` -ValidationCommand "xcodebuild -project PanoPainter.xcodeproj -configuration $Configuration" ` -Prerequisites @( (New-Prerequisite -Name "legacy-xcode-project" -Available (Test-Path -LiteralPath $xcodeProject -PathType Leaf) -Detail $xcodeProject), (New-Prerequisite -Name "xcodebuild" -Available (Test-CommandAvailable "xcodebuild") -Detail "Apple package builder"), (New-Prerequisite -Name "root-cmake-preset" -Available $true -Detail "macos/ios-device/ios-simulator"), (New-Prerequisite -Name "root-cmake-package-target" -Available $false -Detail "Not migrated yet") ) ` -Artifacts @( (New-ArtifactCheck -Name "apple-package-output" -Path $bundleDir -PathType "Container") ) } "webgl" { $webDir = Join-Path $root "out/package/webgl" $readiness += New-PackageReadiness ` -Kind $kind ` -Status "blocked" ` -Reason "emscripten-preset-exists-but-webgl-package-target-missing" ` -ValidationCommand "cmake --build --preset emscripten --target PanoPainter" ` -Prerequisites @( (New-Prerequisite -Name "emcc" -Available (Test-CommandAvailable "emcc") -Detail "Emscripten compiler"), (New-Prerequisite -Name "emcmake" -Available (Test-CommandAvailable "emcmake") -Detail "Emscripten CMake wrapper"), (New-Prerequisite -Name "root-cmake-preset" -Available $true -Detail "emscripten"), (New-Prerequisite -Name "root-cmake-package-target" -Available $false -Detail "Not migrated yet") ) ` -Artifacts @( (New-ArtifactCheck -Name "webgl-output" -Path $webDir -PathType "Container") ) } } } return $readiness } if ($ReadinessOnly) { $elapsed = [int]((Get-Date) - $started).TotalMilliseconds [ordered]@{ command = "package-smoke" preset = $Preset configuration = $Configuration target = $Target stage = "readiness" exitCode = 0 elapsedMs = $elapsed packageReadiness = Get-PackageReadiness -Kinds $PackageKinds } | ConvertTo-Json -Compress -Depth 5 exit 0 } & cmake --build --preset $Preset --config $Configuration --target $Target $buildExitCode = $LASTEXITCODE if ($buildExitCode -ne 0) { $elapsed = [int]((Get-Date) - $started).TotalMilliseconds [ordered]@{ command = "package-smoke" preset = $Preset configuration = $Configuration target = $Target stage = "build" exitCode = $buildExitCode elapsedMs = $elapsed packageReadiness = Get-PackageReadiness -Kinds $PackageKinds } | ConvertTo-Json -Compress exit $buildExitCode } $binaryDir = Join-Path (Join-Path (Join-Path (Get-Location) "out/build/$Preset") $Configuration) "$Target.exe" $dataDir = Join-Path (Join-Path (Join-Path (Get-Location) "out/build/$Preset") $Configuration) "data" $checks = @( [ordered]@{ name = "executable"; path = $binaryDir; exists = Test-Path -LiteralPath $binaryDir -PathType Leaf }, [ordered]@{ name = "data"; path = $dataDir; exists = Test-Path -LiteralPath $dataDir -PathType Container } ) $failed = @($checks | Where-Object { -not $_.exists }) $exitCode = if ($failed.Count -eq 0) { 0 } else { 2 } $elapsedMs = [int]((Get-Date) - $started).TotalMilliseconds [ordered]@{ command = "package-smoke" preset = $Preset configuration = $Configuration target = $Target exitCode = $exitCode elapsedMs = $elapsedMs checks = $checks packageReadiness = Get-PackageReadiness -Kinds $PackageKinds } | ConvertTo-Json -Compress -Depth 5 exit $exitCode