Add package readiness automation guard
This commit is contained in:
@@ -74,6 +74,7 @@ ctest --preset desktop-fast-vcpkg --build-config Debug
|
|||||||
cmake --preset android-arm64
|
cmake --preset android-arm64
|
||||||
powershell -ExecutionPolicy Bypass -File scripts\automation\platform-build.ps1 -Presets android-arm64
|
powershell -ExecutionPolicy Bypass -File scripts\automation\platform-build.ps1 -Presets android-arm64
|
||||||
powershell -ExecutionPolicy Bypass -File scripts\automation\package-smoke.ps1 -Preset windows-msvc-default -Configuration Debug
|
powershell -ExecutionPolicy Bypass -File scripts\automation\package-smoke.ps1 -Preset windows-msvc-default -Configuration Debug
|
||||||
|
powershell -ExecutionPolicy Bypass -File scripts\automation\package-smoke.ps1 -ReadinessOnly
|
||||||
cmake --fresh --preset windows-clangcl-asan
|
cmake --fresh --preset windows-clangcl-asan
|
||||||
python scripts/dev/clangd_nav.py symbols --file src/app_core/brush_ui.h --name execute_brush
|
python scripts/dev/clangd_nav.py symbols --file src/app_core/brush_ui.h --name execute_brush
|
||||||
python scripts/dev/clangd_nav.py symbols --file src/app_core/brush_ui.h --name-regex "execute_.*preset"
|
python scripts/dev/clangd_nav.py symbols --file src/app_core/brush_ui.h --name-regex "execute_.*preset"
|
||||||
@@ -82,6 +83,7 @@ python scripts/dev/clangd_nav.py definition --file src/node_panel_brush.cpp --li
|
|||||||
python scripts/dev/clangd_nav.py references --file src/app_core/brush_ui.h --line 783 --column 45 --path-regex "src[\\/]app_core"
|
python scripts/dev/clangd_nav.py references --file src/app_core/brush_ui.h --line 783 --column 45 --path-regex "src[\\/]app_core"
|
||||||
python scripts/dev/clangd_nav.py self-test
|
python scripts/dev/clangd_nav.py self-test
|
||||||
python scripts/dev/check_platform_build_targets.py
|
python scripts/dev/check_platform_build_targets.py
|
||||||
|
python scripts/dev/check_package_smoke_readiness.py
|
||||||
```
|
```
|
||||||
|
|
||||||
Known local toolchain state:
|
Known local toolchain state:
|
||||||
@@ -143,6 +145,14 @@ Known local toolchain state:
|
|||||||
`panopainter_platform_build_target_matrix_self_test`, verifies the PowerShell
|
`panopainter_platform_build_target_matrix_self_test`, verifies the PowerShell
|
||||||
and shell wrapper defaults include every current CMake test executable plus
|
and shell wrapper defaults include every current CMake test executable plus
|
||||||
the required component and `pano_cli` targets.
|
the required component and `pano_cli` targets.
|
||||||
|
- `package-smoke.ps1 -ReadinessOnly` and `package-smoke.sh --readiness-only`
|
||||||
|
emit the Windows AppX, Android standard/Quest/Focus APK, Apple bundle, and
|
||||||
|
WebGL package readiness matrix without first building an app artifact. The
|
||||||
|
full package smoke command still builds/checks the selected app target before
|
||||||
|
reporting the same readiness matrix. `scripts/dev/check_package_smoke_readiness.py`,
|
||||||
|
registered as `panopainter_package_smoke_readiness_self_test`, verifies both
|
||||||
|
wrappers keep the same six package kinds, blocked DEBT-0011 status, and
|
||||||
|
readiness-only mode.
|
||||||
- Root CMake exposes named `fuzz` and `stress` CTest presets. `fuzz` currently
|
- Root CMake exposes named `fuzz` and `stress` CTest presets. `fuzz` currently
|
||||||
runs deterministic parser/serializer edge tests for binary streams, image
|
runs deterministic parser/serializer edge tests for binary streams, image
|
||||||
metadata, PPI, stroke scripts, and layout XML; `stress` currently runs the
|
metadata, PPI, stroke scripts, and layout XML; `stress` currently runs the
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
# Modernization Debt Log
|
# Modernization Debt Log
|
||||||
|
|
||||||
Status: live
|
Status: live
|
||||||
Last updated: 2026-06-04
|
Last updated: 2026-06-05
|
||||||
|
|
||||||
Every shortcut, temporary adapter, retained vendored dependency, skipped
|
Every shortcut, temporary adapter, retained vendored dependency, skipped
|
||||||
platform gate, compatibility shim, or incomplete automation path must be
|
platform gate, compatibility shim, or incomplete automation path must be
|
||||||
@@ -26,6 +26,12 @@ agent or engineer to remove them without reconstructing context from chat.
|
|||||||
the wrapper defaults against the current CMake test executables, so Android
|
the wrapper defaults against the current CMake test executables, so Android
|
||||||
root CMake validation no longer silently skips newly extracted feature
|
root CMake validation no longer silently skips newly extracted feature
|
||||||
slices. Package targets remain open under DEBT-0009 and DEBT-0011.
|
slices. Package targets remain open under DEBT-0009 and DEBT-0011.
|
||||||
|
- 2026-06-05: DEBT-0011 was narrowed. `package-smoke.ps1` and
|
||||||
|
`package-smoke.sh` now have readiness-only modes that report the same
|
||||||
|
Windows AppX, Android standard/Quest/Focus APK, Apple bundle, and WebGL
|
||||||
|
blocker matrix without requiring an app build first, and
|
||||||
|
`panopainter_package_smoke_readiness_self_test` guards package-kind parity
|
||||||
|
across both wrappers. Package target migration remains open.
|
||||||
- 2026-06-04: DEBT-0036 was narrowed again. Canvas stroke commit,
|
- 2026-06-04: DEBT-0036 was narrowed again. Canvas stroke commit,
|
||||||
thumbnail, and object-draw history paths now query saved blend state through
|
thumbnail, and object-draw history paths now query saved blend state through
|
||||||
tested `pp_renderer_gl` capability-state dispatch; CanvasLayer equirect
|
tested `pp_renderer_gl` capability-state dispatch; CanvasLayer equirect
|
||||||
|
|||||||
@@ -1263,9 +1263,12 @@ keeps the PowerShell and shell wrapper defaults aligned with every current
|
|||||||
CMake test executable plus required component targets.
|
CMake test executable plus required component targets.
|
||||||
`package-smoke` now emits a structured package readiness matrix for Windows
|
`package-smoke` now emits a structured package readiness matrix for Windows
|
||||||
AppX, Android standard/Quest/Focus APKs, Apple bundles, and WebGL output, with
|
AppX, Android standard/Quest/Focus APKs, Apple bundles, and WebGL output, with
|
||||||
blocked prerequisites tied to DEBT-0011. App/package entrypoints still need to
|
blocked prerequisites tied to DEBT-0011. It also has a readiness-only mode for
|
||||||
consume shared targets and remain covered by debt until package validation is
|
cheap package blocker inventory without building an app artifact, and
|
||||||
migrated from legacy package projects to root CMake.
|
`panopainter_package_smoke_readiness_self_test` keeps the PowerShell and shell
|
||||||
|
readiness matrices aligned. 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:
|
Implementation tasks:
|
||||||
|
|
||||||
@@ -1407,6 +1410,7 @@ ctest --preset desktop-fast-vcpkg --build-config Debug
|
|||||||
cmake --preset android-arm64
|
cmake --preset android-arm64
|
||||||
powershell -ExecutionPolicy Bypass -File scripts\automation\platform-build.ps1 -Presets android-arm64
|
powershell -ExecutionPolicy Bypass -File scripts\automation\platform-build.ps1 -Presets android-arm64
|
||||||
powershell -ExecutionPolicy Bypass -File scripts\automation\package-smoke.ps1 -Preset windows-msvc-default -Configuration Debug
|
powershell -ExecutionPolicy Bypass -File scripts\automation\package-smoke.ps1 -Preset windows-msvc-default -Configuration Debug
|
||||||
|
powershell -ExecutionPolicy Bypass -File scripts\automation\package-smoke.ps1 -ReadinessOnly
|
||||||
cmake --fresh --preset windows-clangcl-asan
|
cmake --fresh --preset windows-clangcl-asan
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -2036,7 +2040,9 @@ Results:
|
|||||||
`data/` copy and report structured package readiness for AppX, Android
|
`data/` copy and report structured package readiness for AppX, Android
|
||||||
standard/Quest/Focus APKs, Apple bundles, and WebGL outputs. Actual package
|
standard/Quest/Focus APKs, Apple bundles, and WebGL outputs. Actual package
|
||||||
building remains blocked by DEBT-0011 until those targets are migrated to
|
building remains blocked by DEBT-0011 until those targets are migrated to
|
||||||
root CMake.
|
root CMake. Readiness-only mode now reports the same matrix without building
|
||||||
|
the app first, and the package readiness self-test keeps wrapper package
|
||||||
|
kinds aligned.
|
||||||
- Android arm64 configured with NDK 29.0.14206865 through the platform-build
|
- Android arm64 configured with NDK 29.0.14206865 through the platform-build
|
||||||
wrapper and compiled the refreshed headless component/test matrix, including
|
wrapper and compiled the refreshed headless component/test matrix, including
|
||||||
the current app-core feature-surface automation tests.
|
the current app-core feature-surface automation tests.
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ param(
|
|||||||
[string]$Preset = "windows-msvc-default",
|
[string]$Preset = "windows-msvc-default",
|
||||||
[string]$Configuration = "Debug",
|
[string]$Configuration = "Debug",
|
||||||
[string]$Target = "PanoPainter",
|
[string]$Target = "PanoPainter",
|
||||||
|
[switch]$ReadinessOnly,
|
||||||
[string[]]$PackageKinds = @(
|
[string[]]$PackageKinds = @(
|
||||||
"windows-appx",
|
"windows-appx",
|
||||||
"android-standard-apk",
|
"android-standard-apk",
|
||||||
@@ -207,6 +208,21 @@ function Get-PackageReadiness {
|
|||||||
return $readiness
|
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
|
& cmake --build --preset $Preset --config $Configuration --target $Target
|
||||||
$buildExitCode = $LASTEXITCODE
|
$buildExitCode = $LASTEXITCODE
|
||||||
if ($buildExitCode -ne 0) {
|
if ($buildExitCode -ne 0) {
|
||||||
|
|||||||
@@ -5,6 +5,14 @@ preset="${1:-linux-clang}"
|
|||||||
configuration="${2:-Debug}"
|
configuration="${2:-Debug}"
|
||||||
target="${3:-PanoPainter}"
|
target="${3:-PanoPainter}"
|
||||||
artifact="${4:-out/build/$preset/$target}"
|
artifact="${4:-out/build/$preset/$target}"
|
||||||
|
readiness_only=0
|
||||||
|
if [ "${1:-}" = "--readiness-only" ]; then
|
||||||
|
readiness_only=1
|
||||||
|
preset="${2:-linux-clang}"
|
||||||
|
configuration="${3:-Debug}"
|
||||||
|
target="${4:-PanoPainter}"
|
||||||
|
artifact="${5:-out/build/$preset/$target}"
|
||||||
|
fi
|
||||||
start="$(date +%s)"
|
start="$(date +%s)"
|
||||||
root="$(pwd)"
|
root="$(pwd)"
|
||||||
|
|
||||||
@@ -84,6 +92,14 @@ package_readiness_json() {
|
|||||||
printf ']'
|
printf ']'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if [ "$readiness_only" -eq 1 ]; then
|
||||||
|
end="$(date +%s)"
|
||||||
|
elapsed_ms="$(( (end - start) * 1000 ))"
|
||||||
|
readiness="$(package_readiness_json)"
|
||||||
|
printf '{"command":"package-smoke","preset":"%s","configuration":"%s","target":"%s","stage":"readiness","exitCode":0,"elapsedMs":%s,"packageReadiness":%s}\n' "$preset" "$configuration" "$target" "$elapsed_ms" "$readiness"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
cmake --build --preset "$preset" --config "$configuration" --target "$target"
|
cmake --build --preset "$preset" --config "$configuration" --target "$target"
|
||||||
build_exit="$?"
|
build_exit="$?"
|
||||||
if [ "$build_exit" -ne 0 ]; then
|
if [ "$build_exit" -ne 0 ]; then
|
||||||
|
|||||||
106
scripts/dev/check_package_smoke_readiness.py
Normal file
106
scripts/dev/check_package_smoke_readiness.py
Normal file
@@ -0,0 +1,106 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""Verify package-smoke wrappers report the expected package readiness matrix."""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import json
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
|
||||||
|
EXPECTED_PACKAGE_KINDS = [
|
||||||
|
"windows-appx",
|
||||||
|
"android-standard-apk",
|
||||||
|
"android-quest-apk",
|
||||||
|
"android-focus-apk",
|
||||||
|
"apple-bundle",
|
||||||
|
"webgl",
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def repo_root() -> Path:
|
||||||
|
return Path(__file__).resolve().parents[2]
|
||||||
|
|
||||||
|
|
||||||
|
def powershell_package_kinds(root: Path) -> list[str]:
|
||||||
|
script = (root / "scripts" / "automation" / "package-smoke.ps1").read_text(encoding="utf-8")
|
||||||
|
match = re.search(r"\[string\[\]\]\$PackageKinds\s*=\s*@\((.*?)\n\s*\)", script, re.S)
|
||||||
|
if not match:
|
||||||
|
raise RuntimeError("Could not find PackageKinds default in package-smoke.ps1")
|
||||||
|
return sorted(re.findall(r'"([^"]+)"', match.group(1)))
|
||||||
|
|
||||||
|
|
||||||
|
def shell_package_kinds(root: Path) -> list[str]:
|
||||||
|
script = (root / "scripts" / "automation" / "package-smoke.sh").read_text(encoding="utf-8")
|
||||||
|
return sorted(set(re.findall(r'"kind":"([^"]+)"', script)))
|
||||||
|
|
||||||
|
|
||||||
|
def count_regex(root: Path, patterns: dict[str, str]) -> dict[str, int]:
|
||||||
|
counts: dict[str, int] = {}
|
||||||
|
for script_name, pattern in patterns.items():
|
||||||
|
text = (root / "scripts" / "automation" / script_name).read_text(encoding="utf-8")
|
||||||
|
counts[script_name] = len(re.findall(pattern, text))
|
||||||
|
return counts
|
||||||
|
|
||||||
|
|
||||||
|
def main() -> int:
|
||||||
|
root = repo_root()
|
||||||
|
expected = sorted(EXPECTED_PACKAGE_KINDS)
|
||||||
|
ps_kinds = powershell_package_kinds(root)
|
||||||
|
sh_kinds = shell_package_kinds(root)
|
||||||
|
debt_counts = count_regex(root, {
|
||||||
|
"package-smoke.ps1": r'debt\s*=\s*"DEBT-0011"',
|
||||||
|
"package-smoke.sh": r'"debt":"DEBT-0011"',
|
||||||
|
})
|
||||||
|
blocked_counts = count_regex(root, {
|
||||||
|
"package-smoke.ps1": r'-Status\s+"blocked"',
|
||||||
|
"package-smoke.sh": r'"status":"blocked"',
|
||||||
|
})
|
||||||
|
readiness_mode_counts = {
|
||||||
|
"package-smoke.ps1": (root / "scripts" / "automation" / "package-smoke.ps1").read_text(encoding="utf-8").count("ReadinessOnly"),
|
||||||
|
"package-smoke.sh": (root / "scripts" / "automation" / "package-smoke.sh").read_text(encoding="utf-8").count("readiness_only"),
|
||||||
|
}
|
||||||
|
|
||||||
|
missing = {
|
||||||
|
"package-smoke.ps1": [kind for kind in expected if kind not in ps_kinds],
|
||||||
|
"package-smoke.sh": [kind for kind in expected if kind not in sh_kinds],
|
||||||
|
}
|
||||||
|
unexpected = {
|
||||||
|
"package-smoke.ps1": [kind for kind in ps_kinds if kind not in expected],
|
||||||
|
"package-smoke.sh": [kind for kind in sh_kinds if kind not in expected],
|
||||||
|
}
|
||||||
|
debt_thresholds = {
|
||||||
|
"package-smoke.ps1": 1,
|
||||||
|
"package-smoke.sh": len(expected),
|
||||||
|
}
|
||||||
|
debt_complete = {name: count >= debt_thresholds[name] for name, count in debt_counts.items()}
|
||||||
|
blocked_complete = {name: count >= len(expected) for name, count in blocked_counts.items()}
|
||||||
|
readiness_mode_present = {name: count > 0 for name, count in readiness_mode_counts.items()}
|
||||||
|
|
||||||
|
ok = (
|
||||||
|
all(not values for values in missing.values())
|
||||||
|
and all(not values for values in unexpected.values())
|
||||||
|
and all(debt_complete.values())
|
||||||
|
and all(blocked_complete.values())
|
||||||
|
and all(readiness_mode_present.values())
|
||||||
|
)
|
||||||
|
|
||||||
|
print(json.dumps({
|
||||||
|
"ok": ok,
|
||||||
|
"expectedPackageKinds": expected,
|
||||||
|
"packageKinds": {
|
||||||
|
"package-smoke.ps1": ps_kinds,
|
||||||
|
"package-smoke.sh": sh_kinds,
|
||||||
|
},
|
||||||
|
"missing": missing,
|
||||||
|
"unexpected": unexpected,
|
||||||
|
"debtComplete": debt_complete,
|
||||||
|
"blockedComplete": blocked_complete,
|
||||||
|
"readinessModePresent": readiness_mode_present,
|
||||||
|
}, separators=(",", ":")))
|
||||||
|
return 0 if ok else 1
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
sys.exit(main())
|
||||||
@@ -10,6 +10,11 @@ add_test(NAME panopainter_platform_build_target_matrix_self_test
|
|||||||
set_tests_properties(panopainter_platform_build_target_matrix_self_test PROPERTIES
|
set_tests_properties(panopainter_platform_build_target_matrix_self_test PROPERTIES
|
||||||
LABELS "tooling;desktop-fast")
|
LABELS "tooling;desktop-fast")
|
||||||
|
|
||||||
|
add_test(NAME panopainter_package_smoke_readiness_self_test
|
||||||
|
COMMAND "${Python3_EXECUTABLE}" "${PROJECT_SOURCE_DIR}/scripts/dev/check_package_smoke_readiness.py")
|
||||||
|
set_tests_properties(panopainter_package_smoke_readiness_self_test PROPERTIES
|
||||||
|
LABELS "tooling;desktop-fast")
|
||||||
|
|
||||||
add_library(pp_test_harness INTERFACE)
|
add_library(pp_test_harness INTERFACE)
|
||||||
target_include_directories(pp_test_harness INTERFACE
|
target_include_directories(pp_test_harness INTERFACE
|
||||||
"${CMAKE_CURRENT_SOURCE_DIR}")
|
"${CMAKE_CURRENT_SOURCE_DIR}")
|
||||||
|
|||||||
Reference in New Issue
Block a user