Deploy-Brass: prevent silent loss of launcher metadata in manifest

Two safeguards so a -Stage Pack run never strips launcherVersion/
launcherUrl from the deployed manifest (the original bug that left
old launchers unable to see upgrade prompts):

  1. Always pass -LauncherExePath to Build-Pack.ps1 when a local
     publish exists, regardless of stage. Previously this only fired
     for stages that included Launcher, so Pack-only deploys regressed
     the manifest to a version with no launcher metadata.

  2. New post-deploy verification step fetches the published manifest
     and asserts: pack version matches lockfile, launcherVersion +
     launcherUrl present, all self-hosted URLs use the configured
     manifest host. Throws on any mismatch.
This commit is contained in:
Matt Sijbers
2026-05-20 21:35:39 +01:00
parent 480205a630
commit 4e31f5ab1a
+51 -1
View File
@@ -180,7 +180,16 @@ $manifestPath = Join-Path $here 'manifest.json'
if ($shouldRunPack) {
Step "Regenerate manifest (Build-Pack.ps1)" {
$args = @{ OutputPath = $manifestPath }
if ($shouldRunLauncher -and (Test-Path $launcherExe)) { $args.LauncherExePath = $launcherExe }
# Always embed launcher metadata if a local build exists -- otherwise a
# Stage=Pack deploy silently strips launcherVersion/launcherUrl from the
# published manifest, and old launchers stop seeing upgrade banners.
# Tied to Stage=Launcher only would mean every pack-only deploy regresses.
if (Test-Path $launcherExe) {
$args.LauncherExePath = $launcherExe
} else {
Write-Host " WARNING: launcher exe not found at $launcherExe; manifest will have no launcher metadata." -ForegroundColor Yellow
Write-Host " If you want launcherVersion/launcherUrl populated, run -Stage Launcher (or All) first." -ForegroundColor Yellow
}
& (Join-Path $here 'Build-Pack.ps1') @args | Out-Host
}
}
@@ -236,5 +245,46 @@ if ($shouldRunServer) {
}
}
# ─── Stage 7: verify deployed manifest ────────────────────────────────────
# Fetch what's actually live and assert the fields we expect. Catches:
# - share copy silently failed (clients see old manifest)
# - manifest was written without launcher metadata
# - URLs in the manifest still point at stale hostnames
# Pre-flight already version-checks the OLD manifest; this checks the NEW one.
if ($shouldRunPack -and -not $DryRun -and $ManifestPublicUrl) {
Step "Verify deployed manifest at $ManifestPublicUrl" {
Start-Sleep -Seconds 1 # give the share a moment to flush
$live = $null
try { $live = Invoke-RestMethod -Uri $ManifestPublicUrl -TimeoutSec 8 }
catch { throw "Failed to fetch deployed manifest: $($_.Exception.Message)" }
$expectedHost = ([uri]$ManifestPublicUrl).Host
$problems = @()
$lock = Get-Content (Join-Path $repoRoot 'pack\pack.lock.json') -Raw | ConvertFrom-Json
if ($live.version -ne $lock.version) {
$problems += "version mismatch: live=$($live.version), local=$($lock.version)"
}
if (-not $live.launcherVersion) { $problems += "launcherVersion missing (old launchers won't see upgrade banner)" }
if (-not $live.launcherUrl) { $problems += "launcherUrl missing" }
if ($live.launcherUrl -and ([uri]$live.launcherUrl).Host -ne $expectedHost) {
$problems += "launcherUrl host is $([uri]$live.launcherUrl).Host, expected $expectedHost"
}
# Sample a self-hosted file (skip CDN-hosted mods)
$local = $live.files | Where-Object { $_.url -notmatch 'modrinth|forgecdn|curseforge' } | Select-Object -First 1
if ($local -and ([uri]$local.url).Host -ne $expectedHost) {
$problems += "self-hosted file URL host is $([uri]$local.url).Host, expected $expectedHost (path: $($local.path))"
}
if ($problems.Count -gt 0) {
Write-Host ""
Write-Host "DEPLOYED MANIFEST FAILED VERIFICATION:" -ForegroundColor Red
foreach ($p in $problems) { Write-Host " - $p" -ForegroundColor Red }
throw "Deployed manifest is missing required fields. Fix and redeploy."
}
Write-Host (" version={0} launcherVersion={1} ok" -f $live.version, $live.launcherVersion) -ForegroundColor DarkGray
}
}
Write-Host ""
Write-Host "Deploy finished." -ForegroundColor Green