From 4e31f5ab1ade17a8e337f0ae67325cb13ca47be1 Mon Sep 17 00:00:00 2001 From: Matt Sijbers Date: Wed, 20 May 2026 21:35:39 +0100 Subject: [PATCH] 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. --- scripts/Deploy-Brass.ps1 | 52 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 51 insertions(+), 1 deletion(-) diff --git a/scripts/Deploy-Brass.ps1 b/scripts/Deploy-Brass.ps1 index 640b9b8..554a081 100644 --- a/scripts/Deploy-Brass.ps1 +++ b/scripts/Deploy-Brass.ps1 @@ -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