Files
LlamaCasty/scripts/package-msix.sh
T
gramps daac7689fd TASK 48 slice 2: the app packs as a Microsoft Store MSIX
The manifest the Store route needs, and a real package built from it.

Packaging/Package.appxmanifest is a full-trust packagedClassicApp: EntryPoint
Windows.FullTrustApplication, uap10:TrustLevel=mediumIL,
uap10:RuntimeBehavior=packagedClassicApp, the rescap runFullTrust capability, and
webcam + microphone DeviceCapabilities. That combination is what lets the packaged
app launch the bundled ffmpeg as a child process and write to the user's profile;
an appContainer package would virtualise the recordings folder instead. x64 only,
en-US only (policy 10.7).

Packaging/Assets/ carries the four tiles the packer requires, generated from the
app's own Assets/llamacasty-logo.jpg by scripts/make-store-logos.py - listing art
and app art cannot drift.

scripts/package-msix.sh publishes Release win-x64 self-contained into
artifacts/msix-stage (a RID-less publish would copy every RID's ONNX native),
stages the manifest as AppxManifest.xml + Assets, and runs the Windows SDK's
makeappx. MSIX_PFX/MSIX_PFX_PASSWORD sign a package for a local test install; the
Store signs submissions. artifacts/ is gitignored.

First real package: artifacts/LlamaCasty.msix, 159 MB, 509 files, 'Package
creation succeeded'.

Schema traps found by packing (makeappx reports one error at a time):
Square310x310Logo and Wide310x150Logo are NOT uap:VisualElements attributes - they
live on uap:DefaultTile.

Guard: StorePackagingTests.The_package_manifest_declares_full_trust_camera_and_
microphone - identity/architecture, the full-trust application element, the three
capabilities, no appContainer VALUE (not the file text: the manifest's own comment
says the word), en-US only, and every referenced logo present.

Full suite 438/438, 0 warnings. Cold-start smoke test after the Velopack removal:
MainWindow loaded, no exceptions.
2026-10-22 09:05:50 -07:00

70 lines
2.8 KiB
Bash

#!/usr/bin/env bash
# Build the Microsoft Store MSIX package (TASK 48 item 2).
#
# scripts/package-msix.sh
#
# Publishes the app self-contained for win-x64 (so the package carries its own .NET
# runtime and the ONLY native folders are win-x64 — a RID-less publish copies every
# ONNX Runtime native folder), stages the manifest + logos from Packaging/, and packs
# with the Windows SDK's makeappx.
#
# The result is UNSIGNED (the Store signs the submitted package). To produce a package
# you can install locally for testing, point MSIX_PFX at a self-signed .pfx:
#
# MSIX_PFX=/path/to/dev.pfx MSIX_PFX_PASSWORD=... scripts/package-msix.sh
#
# ⚠️ Before a real submission: set Identity/@Publisher and Properties/P
# PublisherDisplayName in Packaging/Package.appxmanifest to the exact values Partner
# Center shows, and bump Identity/@Version. A mismatch is a certification rejection.
set -euo pipefail
REPO_WSL="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
REPO_WIN="$(wslpath -w "$REPO_WSL")"
DOTNET="/mnt/c/Program Files/dotnet/dotnet.exe"
STAGE_WSL="$REPO_WSL/artifacts/msix-stage"
OUT_WSL="$REPO_WSL/artifacts/LlamaCasty.msix"
MAKEAPPX="$(ls -d "/mnt/c/Program Files (x86)/Windows Kits/10/bin/"*/x64/makeappx.exe 2>/dev/null \
| sort -V | tail -1 || true)"
SIGNTOOL="$(ls -d "/mnt/c/Program Files (x86)/Windows Kits/10/bin/"*/x64/signtool.exe 2>/dev/null \
| sort -V | tail -1 || true)"
[ -x "$MAKEAPPX" ] || { echo "makeappx.exe not found — install the Windows 10/11 SDK." >&2; exit 1; }
echo "== publish (Release, win-x64, self-contained) =="
rm -rf "$STAGE_WSL"
mkdir -p "$STAGE_WSL"
"$DOTNET" publish "$REPO_WIN\\ytLive.csproj" \
-c Release -r win-x64 --self-contained true \
--nologo -v minimal \
-o "$(wslpath -w "$STAGE_WSL")"
[ -f "$STAGE_WSL/ytLive.exe" ] || { echo "publish produced no ytLive.exe" >&2; exit 1; }
[ -d "$STAGE_WSL/ffmpeg" ] || {
echo "ffmpeg/ is missing from the package — it must ship bundled (Store policy 10.2.2)." >&2
exit 1
}
echo "== stage the manifest + logos =="
cp "$REPO_WSL/Packaging/Package.appxmanifest" "$STAGE_WSL/AppxManifest.xml"
cp -r "$REPO_WSL/Packaging/Assets" "$STAGE_WSL/Assets"
echo "== pack =="
"$MAKEAPPX" pack /d "$(wslpath -w "$STAGE_WSL")" /p "$(wslpath -w "$OUT_WSL")" /o
if [ -n "${MSIX_PFX:-}" ]; then
[ -x "$SIGNTOOL" ] || { echo "signtool.exe not found — install the Windows 10/11 SDK." >&2; exit 1; }
echo "== sign =="
if [ -n "${MSIX_PFX_PASSWORD:-}" ]; then
"$SIGNTOOL" sign /fd SHA256 /a /f "$(wslpath -w "$MSIX_PFX")" /p "$MSIX_PFX_PASSWORD" \
"$(wslpath -w "$OUT_WSL")"
else
"$SIGNTOOL" sign /fd SHA256 /a /f "$(wslpath -w "$MSIX_PFX")" "$(wslpath -w "$OUT_WSL")"
fi
else
echo "note: unsigned package (the Store signs submissions); set MSIX_PFX to sign locally."
fi
echo
echo "MSIX: $OUT_WSL ($(du -h "$OUT_WSL" | cut -f1))"