From 21c448d6f11904f4a75fd8aba85ee233f0da8c30 Mon Sep 17 00:00:00 2001 From: omigamedev Date: Wed, 3 Jun 2026 09:57:12 +0200 Subject: [PATCH] Report package smoke readiness matrix --- docs/modernization/debt.md | 2 +- docs/modernization/roadmap.md | 14 +- scripts/automation/package-smoke.ps1 | 203 ++++++++++++++++++++++++++- scripts/automation/package-smoke.sh | 83 ++++++++++- 4 files changed, 294 insertions(+), 8 deletions(-) diff --git a/docs/modernization/debt.md b/docs/modernization/debt.md index cabf8a5..f082fa7 100644 --- a/docs/modernization/debt.md +++ b/docs/modernization/debt.md @@ -29,7 +29,7 @@ agent or engineer to remove them without reconstructing context from chat. | DEBT-0008 | Open | Modernization | `windows-msvc-default` preset is used for local validation because the VS 2026 generator is not installed here | The target VS 2026 preset must remain, but this machine configures with Visual Studio 17 2022 | `cmake --preset windows-msvc-default`; `ctest --preset desktop-fast --build-config Debug` | Validate `windows-vs2026-x64` on a machine with Visual Studio 2026 installed and make it the default Windows validation preset | | DEBT-0009 | Open | Modernization | Android root CMake validation currently builds headless targets only, not APK/package variants; standard arm64/x64, Quest arm64, and Focus/Wave arm64 have named root build presets and share the refreshed `platform-build` component matrix | Platform app entrypoints still live in legacy Gradle/CMake projects and need Phase 6 alignment | `powershell -ExecutionPolicy Bypass -File scripts\automation\platform-build.ps1 -Presets android-arm64`; `cmake --build --preset android-x64`; `cmake --build --preset android-quest-arm64`; `cmake --build --preset android-focus-arm64` | Android standard, Quest, and Focus/Wave package targets consume shared component targets and have package smoke commands | | DEBT-0010 | Open | Modernization | `pp_document` is a pure layer/frame/document/undo-history model with alpha-lock metadata, snapshot construction, per-layer frame metadata, renderer-free RGBA8 face payload storage, snapshot-embedded face-payload validation, renderer-free alpha8 selection-mask storage, PPI import/export helpers, and stroke-script-to-face-payload CLI automation, but it is not yet wired to legacy `Canvas`, legacy save, or legacy action commands | Keep extraction incremental while preserving app behavior | `ctest --preset desktop-fast --build-config Debug`; `pano_cli create-document --width 64 --height 32 --layers 2`; `pano_cli load-project --path tests\data\projects\minimal-project.ppi`; `pp_document_tests`; `pp_document_ppi_import_tests`; `pp_document_ppi_export_tests`; `pano_cli_simulate_document_edits_smoke`; `pano_cli_simulate_document_export_smoke`; `pano_cli_save_document_project_roundtrip_smoke`; `pano_cli_apply_stroke_script_roundtrip_smoke`; `pano_cli_apply_stroke_script_rejects_tiny_canvas` | Legacy document behavior is represented by `pp_document` tests and the app consumes it through a boundary/facade | -| DEBT-0011 | Open | Modernization | `package-smoke` validates the Windows CMake app artifact only, not AppX/APK/Apple/WebGL package outputs | Platform package targets are not migrated to root CMake yet | `powershell -ExecutionPolicy Bypass -File scripts\automation\package-smoke.ps1 -Preset windows-msvc-default -Configuration Debug` | Package-smoke covers Windows AppX, Android APK variants, Apple bundles, and WebGL output where local toolchains are present | +| DEBT-0011 | Open | Modernization | `package-smoke` validates the Windows CMake app artifact and now reports a structured package readiness matrix for Windows AppX, Android standard/Quest/Focus APKs, Apple bundles, and WebGL output, but those package outputs are still `blocked` because root CMake package targets do not exist yet | Platform package targets are not migrated to root CMake yet | `powershell -ExecutionPolicy Bypass -File scripts\automation\package-smoke.ps1 -Preset windows-msvc-default -Configuration Debug`; `bash -n scripts/automation/package-smoke.sh` | Package-smoke builds and validates Windows AppX, Android APK variants, Apple bundles, and WebGL output where local toolchains are present | | DEBT-0012 | Open | Modernization | `pp_ui_core` uses vcpkg tinyxml2 on `windows-msvc-vcpkg-headless`, but retains `pp_vendor_tinyxml2` for default and unproven platform presets | Mobile/AppX/Apple triplets and app packaging still need validation before removing the vendored fallback | `ctest --preset desktop-fast-vcpkg --build-config Debug`; `ctest --preset desktop-fast --build-config Debug`; `powershell -ExecutionPolicy Bypass -File scripts\automation\platform-build.ps1 -Presets android-arm64` | All supported presets consume vcpkg tinyxml2 or document a permanent vendored exception | | DEBT-0013 | Open | Modernization | `pp_assets`, `pp_document`, `pano_cli inspect-project`, `pano_cli load-project`, and `pano_cli save-project` validate the fixed PPI header, thumbnail/body byte layout, generated multi-layer/multi-frame PPI writing with explicit layer opacity/blend/alpha-lock/visibility metadata, per-layer frame durations, metadata-only and targeted dirty-face-payload save/load round-trips, layer/frame index, dirty-face descriptors, dirty-face PNG payload metadata, asset-level RGBA PNG payload decoding, pure document-to-PPI export, CLI document export automation, file-writing document export automation, stroke-script-generated document payload export, and decoded pixel attachment to `pp_document`, but full legacy PPI round-trip parity is not yet extracted | Full PPI save parity requires staged extraction of legacy `Canvas` serialization and image/layer payload handling | `ctest --preset desktop-fast --build-config Debug`; `pp_assets_image_pixels_tests`; `pp_assets_ppi_header_tests`; `pp_document_ppi_import_tests`; `pp_document_ppi_export_tests`; `pano_cli_inspect_project_layout_smoke`; `pano_cli_load_project_metadata_smoke`; `pano_cli_save_project_roundtrip_smoke`; `pano_cli_save_project_payload_roundtrip_smoke`; `pano_cli_simulate_document_export_smoke`; `pano_cli_save_document_project_roundtrip_smoke`; `pano_cli_apply_stroke_script_roundtrip_smoke`; `pano_cli_apply_stroke_script_rejects_tiny_canvas` | Full PPI load/save fixtures cover thumbnails, decoded layer face payloads attached to documents, frames, corrupt payloads, dirty-face payload saving, arbitrary legacy canvas payload/layout combinations, and legacy app round-trip compatibility | | DEBT-0014 | Open | Modernization | `windows-clangcl-asan` now configures as a headless Ninja/clang-cl preset and uses the release MSVC runtime required by ASan, but local builds still fail because installed clang-cl 18.1.8 is paired with VS 2026-preview STL headers that require Clang 20 or newer | Sanitizer validation should be local and repeatable, but this machine's compiler/header pairing is incompatible | `cmake --fresh --preset windows-clangcl-asan`; `cmake --build --preset windows-clangcl-asan --target pp_foundation` | Install/use Clang 20+ with the VS 2026 STL, or point the preset at a compatible VS 2022 toolchain, then make `platform-build.ps1 -Presets windows-clangcl-asan` pass for the headless matrix | diff --git a/docs/modernization/roadmap.md b/docs/modernization/roadmap.md index 254d096..7e74b00 100644 --- a/docs/modernization/roadmap.md +++ b/docs/modernization/roadmap.md @@ -806,8 +806,11 @@ standard x64/arm64, Android Quest arm64, Android Focus/Wave arm64, Emscripten/WebGL, macOS, iOS device, and iOS simulator. `platform-build` automation now builds the current headless component matrix, including `pp_platform_api`, `pp_app_core`, app-core tests, and platform API tests. -App/package entrypoints for non-Windows platforms still need to consume shared -targets and remain covered by debt until package validation is migrated. +`package-smoke` now emits a structured package readiness matrix for Windows +AppX, Android standard/Quest/Focus APKs, Apple bundles, and WebGL output, with +blocked prerequisites tied to DEBT-0011. App/package entrypoints still need to +consume shared targets and remain covered by debt until package validation is +migrated from legacy package projects to root CMake. Implementation tasks: @@ -1251,8 +1254,11 @@ Results: round-trip automation. - Snapshot creation now rejects invalid embedded RGBA8 face payloads before document export or history can persist malformed state. -- PowerShell package-smoke wrapper validates the Windows CMake app executable - and runtime `data/` copy. +- Package-smoke wrappers validate the Windows CMake app executable/runtime + `data/` copy and report structured package readiness for AppX, Android + standard/Quest/Focus APKs, Apple bundles, and WebGL outputs. Actual package + building remains blocked by DEBT-0011 until those targets are migrated to + root CMake. - Android arm64 configured with NDK 29.0.14206865 through the platform-build wrapper and compiled headless foundation/tool/test targets. - Desktop VR drawing now routes generic OpenGL scissor/depth/blend state, diff --git a/scripts/automation/package-smoke.ps1 b/scripts/automation/package-smoke.ps1 index 95317f7..507f94f 100644 --- a/scripts/automation/package-smoke.ps1 +++ b/scripts/automation/package-smoke.ps1 @@ -2,11 +2,210 @@ param( [string]$Preset = "windows-msvc-default", [string]$Configuration = "Debug", - [string]$Target = "PanoPainter" + [string]$Target = "PanoPainter", + [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 +} & cmake --build --preset $Preset --config $Configuration --target $Target $buildExitCode = $LASTEXITCODE @@ -20,6 +219,7 @@ if ($buildExitCode -ne 0) { stage = "build" exitCode = $buildExitCode elapsedMs = $elapsed + packageReadiness = Get-PackageReadiness -Kinds $PackageKinds } | ConvertTo-Json -Compress exit $buildExitCode } @@ -43,6 +243,7 @@ $elapsedMs = [int]((Get-Date) - $started).TotalMilliseconds exitCode = $exitCode elapsedMs = $elapsedMs checks = $checks + packageReadiness = Get-PackageReadiness -Kinds $PackageKinds } | ConvertTo-Json -Compress -Depth 5 exit $exitCode diff --git a/scripts/automation/package-smoke.sh b/scripts/automation/package-smoke.sh index 551eec4..35bcf4b 100644 --- a/scripts/automation/package-smoke.sh +++ b/scripts/automation/package-smoke.sh @@ -6,13 +6,91 @@ configuration="${2:-Debug}" target="${3:-PanoPainter}" artifact="${4:-out/build/$preset/$target}" start="$(date +%s)" +root="$(pwd)" + +json_string() { + printf '"%s"' "$(printf '%s' "$1" | sed 's/\\/\\\\/g; s/"/\\"/g')" +} + +json_bool() { + if [ "$1" = "1" ]; then + printf true + else + printf false + fi +} + +command_available() { + command -v "$1" >/dev/null 2>&1 +} + +file_available() { + [ -f "$1" ] +} + +dir_available() { + [ -d "$1" ] +} + +package_readiness_json() { + windows_wapproj="$root/PanoPainterPackage/PanoPainterPackage.wapproj" + windows_manifest="$root/PanoPainterPackage/Package.appxmanifest" + windows_output="$root/PanoPainterPackage/AppPackages" + android_standard_gradle="$root/android/android/build.gradle" + android_standard_manifest="$root/android/android/src/main/AndroidManifest.xml" + android_standard_output="$root/android/android/build/outputs/apk" + android_quest_gradle="$root/android/quest/build.gradle" + android_quest_manifest="$root/android/quest/src/main/AndroidManifest.xml" + android_quest_output="$root/android/quest/build/outputs/apk" + android_focus_gradle="$root/android/focus/build.gradle" + android_focus_manifest="$root/android/focus/src/main/AndroidManifest.xml" + android_focus_output="$root/android/focus/build/outputs/apk" + apple_project="$root/PanoPainter.xcodeproj/project.pbxproj" + apple_output="$root/out/package/apple" + webgl_output="$root/out/package/webgl" + + file_available "$windows_wapproj"; windows_wapproj_exists="$([ "$?" -eq 0 ] && printf 1 || printf 0)" + file_available "$windows_manifest"; windows_manifest_exists="$([ "$?" -eq 0 ] && printf 1 || printf 0)" + command_available makeappx; makeappx_exists="$([ "$?" -eq 0 ] && printf 1 || printf 0)" + command_available signtool; signtool_exists="$([ "$?" -eq 0 ] && printf 1 || printf 0)" + dir_available "$windows_output"; windows_output_exists="$([ "$?" -eq 0 ] && printf 1 || printf 0)" + + file_available "$android_standard_gradle"; android_standard_gradle_exists="$([ "$?" -eq 0 ] && printf 1 || printf 0)" + file_available "$android_standard_manifest"; android_standard_manifest_exists="$([ "$?" -eq 0 ] && printf 1 || printf 0)" + file_available "$android_quest_gradle"; android_quest_gradle_exists="$([ "$?" -eq 0 ] && printf 1 || printf 0)" + file_available "$android_quest_manifest"; android_quest_manifest_exists="$([ "$?" -eq 0 ] && printf 1 || printf 0)" + file_available "$android_focus_gradle"; android_focus_gradle_exists="$([ "$?" -eq 0 ] && printf 1 || printf 0)" + file_available "$android_focus_manifest"; android_focus_manifest_exists="$([ "$?" -eq 0 ] && printf 1 || printf 0)" + command_available gradle; gradle_exists="$([ "$?" -eq 0 ] && printf 1 || printf 0)" + dir_available "$android_standard_output"; android_standard_output_exists="$([ "$?" -eq 0 ] && printf 1 || printf 0)" + dir_available "$android_quest_output"; android_quest_output_exists="$([ "$?" -eq 0 ] && printf 1 || printf 0)" + dir_available "$android_focus_output"; android_focus_output_exists="$([ "$?" -eq 0 ] && printf 1 || printf 0)" + + file_available "$apple_project"; apple_project_exists="$([ "$?" -eq 0 ] && printf 1 || printf 0)" + command_available xcodebuild; xcodebuild_exists="$([ "$?" -eq 0 ] && printf 1 || printf 0)" + dir_available "$apple_output"; apple_output_exists="$([ "$?" -eq 0 ] && printf 1 || printf 0)" + + command_available emcc; emcc_exists="$([ "$?" -eq 0 ] && printf 1 || printf 0)" + command_available emcmake; emcmake_exists="$([ "$?" -eq 0 ] && printf 1 || printf 0)" + dir_available "$webgl_output"; webgl_output_exists="$([ "$?" -eq 0 ] && printf 1 || printf 0)" + + printf '[' + printf '{"kind":"windows-appx","status":"blocked","reason":"legacy-wapproj-present-but-root-cmake-package-target-missing","debt":"DEBT-0011","validationCommand":"msbuild PanoPainterPackage/PanoPainterPackage.wapproj /p:Configuration=%s /p:Platform=x64","prerequisites":[{"name":"legacy-wapproj","available":%s,"detail":%s},{"name":"appx-manifest","available":%s,"detail":%s},{"name":"makeappx","available":%s,"detail":"Windows SDK packaging tool"},{"name":"signtool","available":%s,"detail":"Windows SDK signing tool"},{"name":"root-cmake-package-target","available":false,"detail":"Not migrated yet"}],"artifacts":[{"name":"app-packages","path":%s,"pathType":"Container","exists":%s}]}' "$configuration" "$(json_bool "$windows_wapproj_exists")" "$(json_string "$windows_wapproj")" "$(json_bool "$windows_manifest_exists")" "$(json_string "$windows_manifest")" "$(json_bool "$makeappx_exists")" "$(json_bool "$signtool_exists")" "$(json_string "$windows_output")" "$(json_bool "$windows_output_exists")" + printf ',{"kind":"android-standard-apk","status":"blocked","reason":"legacy-gradle-package-not-consuming-root-cmake-targets","debt":"DEBT-0011","validationCommand":"gradle -p android/android assembleDebug","prerequisites":[{"name":"gradle-build","available":%s,"detail":%s},{"name":"android-manifest","available":%s,"detail":%s},{"name":"gradle","available":%s,"detail":"Android package builder"},{"name":"root-cmake-preset","available":true,"detail":"android-arm64/android-x64"},{"name":"root-cmake-package-target","available":false,"detail":"Not migrated yet"}],"artifacts":[{"name":"apk-output","path":%s,"pathType":"Container","exists":%s}]}' "$(json_bool "$android_standard_gradle_exists")" "$(json_string "$android_standard_gradle")" "$(json_bool "$android_standard_manifest_exists")" "$(json_string "$android_standard_manifest")" "$(json_bool "$gradle_exists")" "$(json_string "$android_standard_output")" "$(json_bool "$android_standard_output_exists")" + printf ',{"kind":"android-quest-apk","status":"blocked","reason":"legacy-gradle-package-not-consuming-root-cmake-targets","debt":"DEBT-0011","validationCommand":"gradle -p android/quest assembleDebug","prerequisites":[{"name":"gradle-build","available":%s,"detail":%s},{"name":"android-manifest","available":%s,"detail":%s},{"name":"gradle","available":%s,"detail":"Android package builder"},{"name":"root-cmake-preset","available":true,"detail":"android-quest-arm64"},{"name":"root-cmake-package-target","available":false,"detail":"Not migrated yet"}],"artifacts":[{"name":"apk-output","path":%s,"pathType":"Container","exists":%s}]}' "$(json_bool "$android_quest_gradle_exists")" "$(json_string "$android_quest_gradle")" "$(json_bool "$android_quest_manifest_exists")" "$(json_string "$android_quest_manifest")" "$(json_bool "$gradle_exists")" "$(json_string "$android_quest_output")" "$(json_bool "$android_quest_output_exists")" + printf ',{"kind":"android-focus-apk","status":"blocked","reason":"legacy-gradle-package-not-consuming-root-cmake-targets","debt":"DEBT-0011","validationCommand":"gradle -p android/focus assembleDebug","prerequisites":[{"name":"gradle-build","available":%s,"detail":%s},{"name":"android-manifest","available":%s,"detail":%s},{"name":"gradle","available":%s,"detail":"Android package builder"},{"name":"root-cmake-preset","available":true,"detail":"android-focus-arm64"},{"name":"root-cmake-package-target","available":false,"detail":"Not migrated yet"}],"artifacts":[{"name":"apk-output","path":%s,"pathType":"Container","exists":%s}]}' "$(json_bool "$android_focus_gradle_exists")" "$(json_string "$android_focus_gradle")" "$(json_bool "$android_focus_manifest_exists")" "$(json_string "$android_focus_manifest")" "$(json_bool "$gradle_exists")" "$(json_string "$android_focus_output")" "$(json_bool "$android_focus_output_exists")" + printf ',{"kind":"apple-bundle","status":"blocked","reason":"legacy-xcode-project-and-host-toolchain-not-aligned-with-root-cmake-package-target","debt":"DEBT-0011","validationCommand":"xcodebuild -project PanoPainter.xcodeproj -configuration %s","prerequisites":[{"name":"legacy-xcode-project","available":%s,"detail":%s},{"name":"xcodebuild","available":%s,"detail":"Apple package builder"},{"name":"root-cmake-preset","available":true,"detail":"macos/ios-device/ios-simulator"},{"name":"root-cmake-package-target","available":false,"detail":"Not migrated yet"}],"artifacts":[{"name":"apple-package-output","path":%s,"pathType":"Container","exists":%s}]}' "$configuration" "$(json_bool "$apple_project_exists")" "$(json_string "$apple_project")" "$(json_bool "$xcodebuild_exists")" "$(json_string "$apple_output")" "$(json_bool "$apple_output_exists")" + printf ',{"kind":"webgl","status":"blocked","reason":"emscripten-preset-exists-but-webgl-package-target-missing","debt":"DEBT-0011","validationCommand":"cmake --build --preset emscripten --target PanoPainter","prerequisites":[{"name":"emcc","available":%s,"detail":"Emscripten compiler"},{"name":"emcmake","available":%s,"detail":"Emscripten CMake wrapper"},{"name":"root-cmake-preset","available":true,"detail":"emscripten"},{"name":"root-cmake-package-target","available":false,"detail":"Not migrated yet"}],"artifacts":[{"name":"webgl-output","path":%s,"pathType":"Container","exists":%s}]}' "$(json_bool "$emcc_exists")" "$(json_bool "$emcmake_exists")" "$(json_string "$webgl_output")" "$(json_bool "$webgl_output_exists")" + printf ']' +} cmake --build --preset "$preset" --config "$configuration" --target "$target" build_exit="$?" if [ "$build_exit" -ne 0 ]; then end="$(date +%s)" elapsed_ms="$(( (end - start) * 1000 ))" - printf '{"command":"package-smoke","preset":"%s","configuration":"%s","target":"%s","stage":"build","exitCode":%s,"elapsedMs":%s}\n' "$preset" "$configuration" "$target" "$build_exit" "$elapsed_ms" + readiness="$(package_readiness_json)" + printf '{"command":"package-smoke","preset":"%s","configuration":"%s","target":"%s","stage":"build","exitCode":%s,"elapsedMs":%s,"packageReadiness":%s}\n' "$preset" "$configuration" "$target" "$build_exit" "$elapsed_ms" "$readiness" exit "$build_exit" fi @@ -24,5 +102,6 @@ fi end="$(date +%s)" elapsed_ms="$(( (end - start) * 1000 ))" -printf '{"command":"package-smoke","preset":"%s","configuration":"%s","target":"%s","artifact":"%s","exists":%s,"exitCode":%s,"elapsedMs":%s}\n' "$preset" "$configuration" "$target" "$artifact" "$([ "$exit_code" -eq 0 ] && printf true || printf false)" "$exit_code" "$elapsed_ms" +readiness="$(package_readiness_json)" +printf '{"command":"package-smoke","preset":"%s","configuration":"%s","target":"%s","artifact":"%s","exists":%s,"exitCode":%s,"elapsedMs":%s,"packageReadiness":%s}\n' "$preset" "$configuration" "$target" "$artifact" "$([ "$exit_code" -eq 0 ] && printf true || printf false)" "$exit_code" "$elapsed_ms" "$readiness" exit "$exit_code"