diff options
Diffstat (limited to 'packaging')
| -rw-r--r-- | packaging/win/build-win-common.ps1 | 64 | ||||
| -rw-r--r-- | packaging/win/build-win-light.ps1 | 85 | ||||
| -rw-r--r-- | packaging/win/build-win.ps1 | 43 | ||||
| -rw-r--r-- | packaging/win/electron-builder.light.yml | 54 |
4 files changed, 216 insertions, 30 deletions
diff --git a/packaging/win/build-win-common.ps1 b/packaging/win/build-win-common.ps1 new file mode 100644 index 0000000..e60abc5 --- /dev/null +++ b/packaging/win/build-win-common.ps1 @@ -0,0 +1,64 @@ +<# +.SYNOPSIS + Steps shared by build-win.ps1 (Full) and build-win-light.ps1 (Light). + +.DESCRIPTION + Dot-sourced, not run directly -- it defines functions, it does not call + them. The two orchestrators differ only in whether they freeze a node + runtime and which electron-builder config they hand to the final step; + everything before that (Node version check, npm ci, the Electron-bump + policy, sync-ui) is identical, and living in one place means it cannot + drift between the two the way a copy-paste would. + + Every function assumes it runs from packages/meshbay-client (both + orchestrators Push-Location there first). +#> + +function Step($msg) { Write-Host "==> $msg" -ForegroundColor Cyan } + +function Assert-NodeVersion { + if (-not (Get-Command node -ErrorAction SilentlyContinue)) { + throw "Node.js not found. Install Node 22 or newer from nodejs.org." + } + $nodeMajor = [int](& node -e "process.stdout.write(String(process.versions.node.split('.')[0]))") + if ($nodeMajor -lt 22) { throw "Node $nodeMajor is too old -- need 22 or newer for Electron" } + Step "Node $(& node --version)" +} + +function Invoke-NpmCi { + Step "npm ci" + & npm ci --ignore-scripts + if ($LASTEXITCODE -ne 0) { throw "npm ci failed" } +} + +# Chromium-CVE policy: build against the latest Electron release unless +# -NoElectronBump was passed. Writes package.json + package-lock.json when it +# actually bumps something (that is by design -- commit the new pin); the +# Chromium download itself always runs, bump or not, same as before this was +# factored out. +function Invoke-ElectronBump { + param( + [switch]$NoElectronBump, + [Parameter(Mandatory = $true)][string]$WinDir + ) + if (-not $NoElectronBump) { + Step "checking for a newer Electron" + $bumped = & node (Join-Path $WinDir "bump-electron.mjs") + if ($LASTEXITCODE -ne 0) { throw "electron bump failed" } + if ($bumped) { + Write-Host " Electron -> $bumped (package.json + lock updated, commit them)" -ForegroundColor Yellow + } else { + Write-Host " Electron is already current" + } + } + + Step "downloading Electron's Chromium" + & npm approve-scripts electron 2>$null + & node node_modules/electron/install.js +} + +function Invoke-SyncUi { + Step "npm run sync-ui" + & npm run sync-ui + if ($LASTEXITCODE -ne 0) { throw "sync-ui failed" } +} diff --git a/packaging/win/build-win-light.ps1 b/packaging/win/build-win-light.ps1 new file mode 100644 index 0000000..5a8a06e --- /dev/null +++ b/packaging/win/build-win-light.ps1 @@ -0,0 +1,85 @@ +<# +.SYNOPSIS + Build the Windows "Light" installer: Electron client + UI only, no + bundled node. + +.DESCRIPTION + The counterpart of build-win.ps1 (Full) for anyone who only wants to + *use* MeshBay -- join groups, chat, browse, download, stream, cast -- + without ever hosting content from this machine. See + C:\Users\admin\devel\light-client.md for the evaluation this + implements: a member never needs a local node to begin with (identity + keys are per node -- the *host's* node, not the joiner's), so Light is + the existing browser-only usage pattern wrapped in the Electron shell, + minus the frozen meshbay-node.exe / ffmpeg / autostart bundle. + + Steps 1-4 are identical to build-win.ps1 (build-win-common.ps1). Step 5, + PyInstaller freezing a node runtime, does not happen at all -- that is + the entire point of this target. Step 6 hands electron-builder a + standalone config (electron-builder.light.yml) instead of package.json's + `build` field: passing --config makes electron-builder read ONLY that + file (see app-builder-lib/out/util/config/load.js's getConfig -- when a + config path is given, package.json's own `build` field is never loaded, + so there is no array-merge ambiguity to worry about between the two + targets' very different extraResources). + + Output: packages/meshbay-client/dist-light/MeshBay Light-Setup-<version>.exe + (a different output directory from Full's dist/, so the two builds never + race on the same files). + +.PARAMETER NoElectronBump + Keep the pinned Electron instead of upgrading to the latest release. +#> +[CmdletBinding()] +param( + [switch]$NoElectronBump +) + +$ErrorActionPreference = "Stop" +Set-StrictMode -Version Latest + +$WinDir = $PSScriptRoot +$Repo = (Resolve-Path (Join-Path $WinDir "..\..")).Path +$Client = Join-Path $Repo "packages\meshbay-client" +$Config = Join-Path $WinDir "electron-builder.light.yml" + +. (Join-Path $WinDir "build-win-common.ps1") + +if (-not (Test-Path $Config)) { throw "missing $Config" } + +# --- 1. Node ------------------------------------------------------------- +Assert-NodeVersion + +Push-Location $Client +try { + # --- 2. deps ------------------------------------------------------ + Invoke-NpmCi + + # --- 3. Electron: build against the latest release -------------- + Invoke-ElectronBump -NoElectronBump:$NoElectronBump -WinDir $WinDir + + # --- 4. UI ----------------------------------------------------- + Invoke-SyncUi + + # --- 5. (no node runtime -- that is what makes this "Light") ----- + + # --- 6. installer --------------------------------------- + Step "electron-builder --win nsis --config electron-builder.light.yml" + & npx electron-builder --win nsis --config $Config + if ($LASTEXITCODE -ne 0) { throw "electron-builder failed" } +} +finally { + Pop-Location +} + +$setup = Get-ChildItem (Join-Path $Client "dist-light") -Filter "*Setup*.exe" -ErrorAction SilentlyContinue | + Sort-Object LastWriteTime | Select-Object -Last 1 +Write-Host "" +if ($setup) { + Write-Host "OK installer: $($setup.FullName)" -ForegroundColor Green + Write-Host (" ({0:N0} MB)" -f ($setup.Length / 1MB)) +} +else { + Write-Host "!! no *Setup*.exe found in $Client\dist-light" -ForegroundColor Red + exit 1 +} diff --git a/packaging/win/build-win.ps1 b/packaging/win/build-win.ps1 index 0a30ad5..ea54c6f 100644 --- a/packaging/win/build-win.ps1 +++ b/packaging/win/build-win.ps1 @@ -9,13 +9,18 @@ meshbay-node daemon. No hub -- a desktop machine installs client + node (+ common, which is inside the node runtime). + This is the "Full" target. See build-win-light.ps1 for "Light" (client + + UI only, no bundled node) -- steps 1-4 below live in build-win-common.ps1, + shared by both, so they cannot drift apart. + Steps: 1. Node >= 22 check 2. npm ci (+ approve Electron's install script, download Chromium) 3. bump Electron to the latest release (Chromium CVE policy -- see build-client.sh; skip with -NoElectronBump) 4. npm run sync-ui (copy the interface from the hub package) - 5. build-node-runtime.ps1 (PyInstaller freeze of the daemon) + 5. build-node-runtime.ps1 (PyInstaller freeze of the daemon) -- Light + skips this step entirely, which is the whole difference 6. electron-builder --win nsis .PARAMETER SkipFfmpeg @@ -44,45 +49,23 @@ $WinDir = $PSScriptRoot $Repo = (Resolve-Path (Join-Path $WinDir "..\..")).Path $Client = Join-Path $Repo "packages\meshbay-client" -function Step($msg) { Write-Host "==> $msg" -ForegroundColor Cyan } +. (Join-Path $WinDir "build-win-common.ps1") # --- 1. Node ------------------------------------------------------------- -if (-not (Get-Command node -ErrorAction SilentlyContinue)) { - throw "Node.js not found. Install Node 22 or newer from nodejs.org." -} -$nodeMajor = [int](& node -e "process.stdout.write(String(process.versions.node.split('.')[0]))") -if ($nodeMajor -lt 22) { throw "Node $nodeMajor is too old -- need 22 or newer for Electron" } -Step "Node $(& node --version)" +Assert-NodeVersion Push-Location $Client try { # --- 2. deps ------------------------------------------------------ - Step "npm ci" - & npm ci --ignore-scripts - if ($LASTEXITCODE -ne 0) { throw "npm ci failed" } + Invoke-NpmCi # --- 3. Electron: build against the latest release -------------- - # Writes package.json + package-lock.json, so the build leaves the repo - # dirty on purpose -- commit the new pin. - if (-not $NoElectronBump) { - Step "checking for a newer Electron" - $bumped = & node (Join-Path $WinDir "bump-electron.mjs") - if ($LASTEXITCODE -ne 0) { throw "electron bump failed" } - if ($bumped) { - Write-Host " Electron -> $bumped (package.json + lock updated, commit them)" -ForegroundColor Yellow - } else { - Write-Host " Electron is already current" - } - } - - Step "downloading Electron's Chromium" - & npm approve-scripts electron 2>$null - & node node_modules/electron/install.js + # Writes package.json + package-lock.json when it bumps something, so the + # build leaves the repo dirty on purpose -- commit the new pin. + Invoke-ElectronBump -NoElectronBump:$NoElectronBump -WinDir $WinDir # --- 4. UI ----------------------------------------------------- - Step "npm run sync-ui" - & npm run sync-ui - if ($LASTEXITCODE -ne 0) { throw "sync-ui failed" } + Invoke-SyncUi # --- 5. node runtime --------------------------------------- $rtExe = Join-Path $Client "node-runtime\meshbay-node.exe" diff --git a/packaging/win/electron-builder.light.yml b/packaging/win/electron-builder.light.yml new file mode 100644 index 0000000..155ffa6 --- /dev/null +++ b/packaging/win/electron-builder.light.yml @@ -0,0 +1,54 @@ +# Standalone electron-builder config for the "Light" Windows target: Electron +# client + UI, no bundled node. Deliberately NOT layered onto package.json's +# `build` field -- passed via `electron-builder --config <this file>`, which +# reads ONLY this file (app-builder-lib/out/util/config/load.js's getConfig: +# a given configPath replaces package.json's own "build", it does not merge +# with it). That is what keeps Light's extraResources from ever accidentally +# inheriting Full's frozen daemon and its two service scripts through some +# array-merge surprise -- there is nothing to merge. +# +# Invoked from packages/meshbay-client (see build-win-light.ps1), so every +# relative path below resolves the same way package.json's `build` field's +# already do. +# +# See C:\Users\admin\devel\light-client.md for the evaluation this +# implements. + +appId: org.meshbay.client.light +productName: MeshBay Light + +directories: + # Full's own build lives in dist/ -- a separate output dir means the two + # targets never race on, or clobber, each other's files. + output: dist-light + +files: + - src/** + - ui/** + +win: + target: nsis + icon: build/icon.ico + artifactName: "MeshBay-Light-Setup-${version}.${ext}" + extraResources: + # firewall.ps1 needs no Light-specific fork: `add` already does + # `if (-not (Test-Path $r.Path)) { skip }` per rule, and the "MeshBay + # Node" rule's target -- the frozen daemon, inside the folder this + # config never ships -- simply is not here. One script, one source of + # truth; it just silently adds the 3 rules that apply (client WebRTC + # ICE + the 2 LAN-casting rules) and logs the node rule as skipped. + - from: ../../packaging/win/firewall.ps1 + to: firewall.ps1 + +nsis: + oneClick: false + perMachine: false + allowElevation: false + allowToChangeInstallationDirectory: true + createDesktopShortcut: true + createStartMenuShortcut: true + deleteAppDataOnUninstall: false + runAfterFinish: true + # Resolved against buildResourcesDir (build/), same as Full's implicit + # default of build/installer.nsh -- see platformPackager.js's getResource. + include: installer-light.nsh |