PrintToVeraeTimeStamp/platform/windows/scripts/build-tray-msi.ps1
George Lambert 46fa1aa0d4 feat: MSI full outline, silent props, HelperVersion NSIS sync, CERT fonts plan
TODO-6 L1/I1/L7/I7 — commercial + CERT next-level scaffolds.
2026-10-13 23:23:45 -04:00

184 lines
6.7 KiB
PowerShell

#Requires -Version 5.1
<#
.SYNOPSIS
Build the per-user Verae Tray presence MSI (WiX v3 candle/light) when available.
.DESCRIPTION
Stages verae-tray.ps1 + common.ps1, stamps ProductVersion from
internal/job.HelperVersion via Get-VeraePackageVersion (or $env:VERSION),
then runs candle.exe + light.exe if on PATH (or under Program Files WiX).
If WiX Toolset is missing, prints an install tip and exits 0 without failing
the day-to-day tray path (use build-tray-startmenu.ps1 instead).
Scope: non-elevated per-user tray shortcuts only — not the full commercial MSI.
.EXITCODES
0 Success: MSI built, or WiX missing and tip printed (default; day-to-day OK).
1 Failure: -SkipTip with WiX missing; missing .wxs/tray payload; candle/light
non-zero; or Write-Error / unhandled terminating error ($ErrorActionPreference Stop).
.PARAMETER Version
Override package version (default: Get-VeraePackageVersion / HelperVersion).
.PARAMETER OutDir
Output directory for .wixobj and .msi (default: platform/windows/wix/out).
.PARAMETER StageDir
Staging directory for payload files (default: platform/windows/wix/Stage).
.PARAMETER WixDir
Directory containing VeraeTrayShortcuts.wxs (+ fragment).
.PARAMETER SkipTip
When candle/light are missing, exit 1 instead of printing the install tip.
.EXAMPLE
powershell -NoProfile -ExecutionPolicy Bypass -File build-tray-msi.ps1
$env:VERSION = "0.3.7"; .\build-tray-msi.ps1
#>
param(
[string]$Version = "",
[string]$OutDir = "",
[string]$StageDir = "",
[string]$WixDir = "",
[switch]$SkipTip
)
$ErrorActionPreference = "Stop"
$common = Join-Path $PSScriptRoot "common.ps1"
if (Test-Path -LiteralPath $common) { . $common }
if (-not $Version) {
if (Get-Command Get-VeraePackageVersion -ErrorAction SilentlyContinue) {
$Version = Get-VeraePackageVersion
} elseif ($env:VERSION -and $env:VERSION.Trim()) {
$Version = $env:VERSION.Trim()
} else {
$Version = "0.3.6"
}
}
if (-not $WixDir) {
$WixDir = Join-Path (Split-Path -Parent $PSScriptRoot) "wix"
}
if (-not $StageDir) {
$StageDir = Join-Path $WixDir "Stage"
}
if (-not $OutDir) {
$OutDir = Join-Path $WixDir "out"
}
$productWxs = Join-Path $WixDir "VeraeTrayShortcuts.wxs"
$fragmentWxs = Join-Path $WixDir "VeraeTrayShortcutsFragment.wxs"
if (-not (Test-Path -LiteralPath $productWxs)) {
Write-Error "Missing WiX product: $productWxs"
}
if (-not (Test-Path -LiteralPath $fragmentWxs)) {
Write-Error "Missing WiX fragment: $fragmentWxs"
}
function Find-WixTool([string]$Name) {
$cmd = Get-Command $Name -ErrorAction SilentlyContinue
if ($cmd -and $cmd.Source) { return $cmd.Source }
$cmdExe = Get-Command "$Name.exe" -ErrorAction SilentlyContinue
if ($cmdExe -and $cmdExe.Source) { return $cmdExe.Source }
$roots = @()
if (${env:ProgramFiles(x86)}) { $roots += ${env:ProgramFiles(x86)} }
if ($env:ProgramFiles) { $roots += $env:ProgramFiles }
if ($env:WIX) {
$wixBin = Join-Path $env:WIX "bin"
if (Test-Path -LiteralPath $wixBin) { $roots = @($wixBin) + $roots }
}
foreach ($root in $roots) {
if (-not $root -or -not (Test-Path -LiteralPath $root)) { continue }
$direct = Join-Path $root "$Name.exe"
if (Test-Path -LiteralPath $direct) { return (Resolve-Path -LiteralPath $direct).Path }
Get-ChildItem -LiteralPath $root -Directory -Filter "WiX Toolset*" -ErrorAction SilentlyContinue |
ForEach-Object {
$bin = Join-Path $_.FullName "bin\$Name.exe"
if (Test-Path -LiteralPath $bin) { return (Resolve-Path -LiteralPath $bin).Path }
}
}
return $null
}
$candle = Find-WixTool "candle"
$light = Find-WixTool "light"
Write-Host "Verae tray presence MSI (skeleton)"
Write-Host " ProductVersion: $Version (HelperVersion / Get-VeraePackageVersion)"
Write-Host " WixDir: $WixDir"
Write-Host " StageDir: $StageDir"
Write-Host " OutDir: $OutDir"
if (-not $candle -or -not $light) {
Write-Host ""
Write-Host "WiX Toolset (candle/light) not found on PATH or under Program Files."
Write-Host "No MSI produced. Day-to-day tray presence:"
Write-Host " powershell -NoProfile -ExecutionPolicy Bypass -File `"$(Join-Path $PSScriptRoot 'build-tray-startmenu.ps1')`""
Write-Host ""
Write-Host "Install WiX tip (Windows host or CI runner):"
Write-Host " 1. Download WiX Toolset v3.14+ from https://wixtoolset.org/ (or winget install --id WiXToolset.WiX)"
Write-Host " 2. Add candle.exe and light.exe to PATH, e.g.:"
Write-Host " set PATH=%PATH%;%ProgramFiles(x86)%\WiX Toolset v3.14\bin"
Write-Host " 3. Re-run this script: build-tray-msi.ps1"
Write-Host " WiX v4 (dotnet tool install --global wix) needs authoring adapted to v4 namespaces."
Write-Host " See platform/windows/wix/README.md"
if ($SkipTip) { exit 1 }
exit 0
}
Write-Host " candle: $candle"
Write-Host " light: $light"
# Stage payload next to .wxs expectations (Stage\verae-tray.ps1, Stage\common.ps1).
New-Item -ItemType Directory -Force -Path $StageDir | Out-Null
New-Item -ItemType Directory -Force -Path $OutDir | Out-Null
$traySrc = Join-Path $PSScriptRoot "verae-tray.ps1"
$commonSrc = Join-Path $PSScriptRoot "common.ps1"
if (-not (Test-Path -LiteralPath $traySrc)) {
Write-Error "Missing tray script: $traySrc"
}
Copy-Item -LiteralPath $traySrc -Destination (Join-Path $StageDir "verae-tray.ps1") -Force
if (Test-Path -LiteralPath $commonSrc) {
Copy-Item -LiteralPath $commonSrc -Destination (Join-Path $StageDir "common.ps1") -Force
} else {
Write-Warning "common.ps1 not found; MSI will still require it at light time if Component is present."
}
$stageAbs = (Resolve-Path -LiteralPath $StageDir).Path
$outAbs = (Resolve-Path -LiteralPath $OutDir).Path
$wixAbs = (Resolve-Path -LiteralPath $WixDir).Path
Write-Host "Staging done. Running candle..."
& $candle -nologo -out (Join-Path $outAbs "\") `
"-dProductVersion=$Version" `
"-dStageDir=$stageAbs" `
(Join-Path $wixAbs "VeraeTrayShortcuts.wxs") `
(Join-Path $wixAbs "VeraeTrayShortcutsFragment.wxs")
if ($LASTEXITCODE -ne 0) {
Write-Error "candle failed with exit $LASTEXITCODE"
}
$msiName = "VeraeTray-$Version-peruser.msi"
$msiPath = Join-Path $outAbs $msiName
Write-Host "Running light -> $msiPath"
& $light -nologo -out $msiPath `
(Join-Path $outAbs "VeraeTrayShortcuts.wixobj") `
(Join-Path $outAbs "VeraeTrayShortcutsFragment.wixobj")
if ($LASTEXITCODE -ne 0) {
Write-Error "light failed with exit $LASTEXITCODE"
}
Write-Host ""
Write-Host "Built: $msiPath"
Write-Host " ProductVersion=$Version (from HelperVersion / Get-VeraePackageVersion)."
Write-Host " Per-user, non-elevated tray presence only — not full commercial MSI."
Write-Host " Silent: msiexec /i `"$msiPath`" /qn VERAE_IPP_ADDR=127.0.0.1:8631"
Write-Host " Hold ids are never evidence."
exit 0