build: the exe is LlamaCasty.exe, and the publish script proves the artifact

Renames AssemblyName to LlamaCasty before the first Steam depot — Steamworks is explicit
that renaming a live exe is painful, so this had to land first, not later.

Four assembly-qualified pack URIs carried the old name, not three: MainWindow (window
icon), OverlayHost (logo), RenameRecordingDialog and KeepBroadcastDialog. Pack URIs
resolve by assembly name at runtime, so a stale one compiles, passes every test and then
silently renders nothing the first time that view opens. AssemblyIdentityTests guards
both halves — the assembly name, and no source XAML still naming the legacy assembly.
Packaging/Package.appxmanifest and package-msix.sh carry the exe name too.

scripts/publish.sh replaces the by-hand publish: single-file win-x64, ReadyToRun,
ffmpeg beside the exe, and it refuses to finish if ffmpeg, LICENSE, PRIVACY.md or
THIRD-PARTY-NOTICES.txt are missing, or if a test assembly leaked in.

That last guard exists because the first publish was wrong in a way no test could see:
PublishSingleFile + IncludeNativeLibrariesForSelfExtract bundled the libav*.dll family
into the exe — a 9-file output with no ffmpeg folder and a 182 MB binary, so the locator
would have found nothing at runtime. ExcludeFromSingleFile="true" on the content keeps
the folder a folder. Diffing against a control publish without the single-file flags
found it; guessing at item globs wasted two attempts first (recorded in MyMistakes.md).

Measured: 127 MB exe + 129 MB ffmpeg = 257 MB depot. Tests: AssemblyIdentity,
StorePackaging, BuildStamp, BundledFonts all pass; app builds with 0 warnings.
This commit is contained in:
2026-11-01 07:01:50 -08:00
parent 8f79b20a18
commit abfab25685
15 changed files with 240 additions and 54 deletions
+29
View File
@@ -166,6 +166,35 @@ in Studio → Settings → Channel → **Feature eligibility**:
*"Advanced YouTube features aren't available for this account"*. If ID verification is ever
wanted on a personal channel, do it **before** converting to a brand account.
### THE SINGLE-FILE PUBLISHER EATS ffmpeg (2026-11-01)
**Problem:** `dotnet publish` with `PublishSingleFile=true` +
`IncludeNativeLibrariesForSelfExtract=true` produced a **9-file** output with **no `ffmpeg\`
folder** and a **182 MB exe** — the libav\*.dll family had been bundled *inside* the binary. The
build was green, the tests passed, and the app would have shipped unable to find ffmpeg at
runtime (the locator looks for `ffmpeg\ffmpeg.exe` beside the exe).
**Diagnosis that worked:** diff the publish output against a **control publish with the
single-file flags removed** — ffmpeg was there. Then add flags back one at a time;
`IncludeNativeLibrariesForSelfExtract` was the one that broke it.
**Fix:** mark the content `ExcludeFromSingleFile="true"`.
```xml
<None Include="ffmpeg\**" CopyToOutputDirectory="PreserveNewest"
CopyToPublishDirectory="Always" ExcludeFromSingleFile="true" />
```
After: 127 MB exe, `ffmpeg\` present, depot ≈ 257 MB total.
- ⚠️ **The `<None Remove="ffmpeg\**" />` before it is not the fix** — it silences a duplicate-item
warning from the SDK's default glob, and I tried it first and wrongly believed it had worked.
Two failed remedies in a row is the research trigger: read the publisher's own metadata
(`ExcludeFromSingleFile`) instead of guessing at item globs.
- ⚠️ **A clean build and green tests cannot see this.** Only the artifact can, which is why
`scripts/publish.sh` fails loudly when `ffmpeg\`, `LICENSE`, `PRIVACY.md` or
`THIRD-PARTY-NOTICES.txt` are missing, and when test assemblies leak in.
### STEAM IS THE DISTRIBUTOR — AND WHAT IT DOES NOT ALLOW (2026-10-31)
**Why recorded:** the distribution answer changed three times in one day (winget → zip+GitHub →