diff options
Diffstat (limited to 'packaging/win/build-node-runtime.ps1')
| -rw-r--r-- | packaging/win/build-node-runtime.ps1 | 62 |
1 files changed, 50 insertions, 12 deletions
diff --git a/packaging/win/build-node-runtime.ps1 b/packaging/win/build-node-runtime.ps1 index c6a8af1..24baa0b 100644 --- a/packaging/win/build-node-runtime.ps1 +++ b/packaging/win/build-node-runtime.ps1 @@ -1,10 +1,12 @@ <# .SYNOPSIS - Freeze the MeshBay node daemon into a relocatable Windows binary. + Freeze the MeshBay node daemon, and the command-line client beside it, + into relocatable Windows binaries. .DESCRIPTION - Produces packages/meshbay-client/node-runtime/meshbay-node.exe (+ its - onedir payload) with PyInstaller. electron-builder then carries that tree + Produces packages/meshbay-client/node-runtime/meshbay-node.exe, + meshbay-nodew.exe and meshbay-cli.exe (+ their shared onedir payload) + with PyInstaller. electron-builder then carries that tree into the NSIS installer as an extraResource (see package.json build.win). The frozen binary is what the desktop client spawns and what the W3 @@ -76,11 +78,12 @@ if ($verMajor -lt 3 -or ($verMajor -eq 3 -and $verMinor -lt 12)) { Step "python $verMajor.$verMinor ($Python)" # --- 2. dependencies ----------------------------------------------------- -Step "installing meshbay-common, meshbay-node and PyInstaller" +Step "installing meshbay-common, meshbay-node, meshbay-cli and PyInstaller" & $Python -m pip install --upgrade pip --quiet & $Python -m pip install --quiet ` (Join-Path $Repo "packages\meshbay-common") ` (Join-Path $Repo "packages\meshbay-node") ` + (Join-Path $Repo "packages\meshbay-cli") ` "pyinstaller>=6.10" ` "tzdata" # tzdata: Windows ships no IANA zone database, so zoneinfo (pulled in @@ -88,6 +91,15 @@ Step "installing meshbay-common, meshbay-node and PyInstaller" # 'Hidden import "tzdata" not found' when it is absent. if ($LASTEXITCODE -ne 0) { throw "pip install failed" } +# Known vulnerabilities in what is about to be frozen: one stops the build +# unless packaging\pip-audit-ignore.txt says why it does not apply; no network +# only skips the audit, with a warning. pip-audit runs from a venv of its own, +# never from the one PyInstaller freezes. +Step "auditing dependencies (pip-audit)" +& $Python (Join-Path $Repo "packaging\audit_deps.py") ` + --tool-dir (Join-Path $Client "build\_pip-audit") +if ($LASTEXITCODE -ne 0) { throw "pip-audit found known vulnerabilities" } + # --- 3. freeze -------------------------------------------------------- if (Test-Path $OutDir) { Remove-Item -Recurse -Force $OutDir } $pyiWork = Join-Path $Client "build\_pyinstaller" @@ -105,7 +117,7 @@ finally { } $frozen = Join-Path $pyiDist "meshbay-node" -foreach ($name in "meshbay-node.exe", "meshbay-nodew.exe") { +foreach ($name in "meshbay-node.exe", "meshbay-nodew.exe", "meshbay-cli.exe") { if (-not (Test-Path (Join-Path $frozen $name))) { throw "PyInstaller did not produce $name at $frozen" } @@ -124,7 +136,7 @@ Copy-Item (Join-Path $Repo "packages\meshbay-common\COPYING.LESSER") (Join-Path Copy-Item (Join-Path $Repo "packages\meshbay-common\COPYING") (Join-Path $frozen "LICENSE-GPL-3.0.txt") & $Python (Join-Path $Repo "packaging\third_party_notices.py") ` -o (Join-Path $frozen "THIRD-PARTY-NOTICES.txt") ` - meshbay-node tzdata --extra pyinstaller --with-python + meshbay-node meshbay-cli tzdata --extra pyinstaller --with-python if ($LASTEXITCODE -ne 0) { throw "third_party_notices.py failed" } # --- 4. ffmpeg (bundled by default) ----------------------------------- @@ -137,8 +149,9 @@ else { } # --- 5. default.env (shared TMDB token) ------------------------------ -# Copied as is from QE\default.env (never versioned), one line: -# MESHBAY_TMDB_DEFAULT_TOKEN=eyJ... Beside the exe, where +# Taken from QE\default.env (never versioned). Only its first line ships, and +# only once it is exactly MESHBAY_TMDB_DEFAULT_TOKEN=<JWT>: anything else +# written in that file stays out of a public package. Beside the exe, where # platform.packaged_default_env() looks for it. The daemon reads it beneath # %LOCALAPPDATA%\meshbay\node.env and the operator's own token, so it is only # the fallback. No token, no build: an empty one goes unnoticed. The check is @@ -147,11 +160,13 @@ $defaultEnv = Join-Path $Repo "QE\default.env" $text = if (Test-Path -LiteralPath $defaultEnv) { [System.Text.Encoding]::ASCII.GetString([System.IO.File]::ReadAllBytes($defaultEnv)) } else { "" } -if (-not $text.StartsWith("MESHBAY_TMDB_DEFAULT_TOKEN=eyJ")) { - throw "$defaultEnv missing, or not starting with MESHBAY_TMDB_DEFAULT_TOKEN=eyJ... (no BOM)" +$tokenLine = ($text -split "`n", 2)[0].TrimEnd("`r") +if ($tokenLine -cnotmatch '^MESHBAY_TMDB_DEFAULT_TOKEN=eyJ[A-Za-z0-9_.-]+$') { + throw "$defaultEnv missing, or its first line is not MESHBAY_TMDB_DEFAULT_TOKEN=eyJ... (no BOM)" } -Copy-Item -LiteralPath $defaultEnv (Join-Path $frozen "default.env") -Step "default.env copied from QE\" +[System.IO.File]::WriteAllText((Join-Path $frozen "default.env"), "$tokenLine`n", + (New-Object System.Text.UTF8Encoding $false)) +Step "default.env: token line taken from QE\" # --- 6. publish ---------------------------------------------------- Move-Item $frozen $OutDir @@ -198,6 +213,29 @@ Step "smoke test: the frozen node as a connection process" & $Python (Join-Path $WinDir "smoke-connection-process.py") $exe (Join-Path $OutDir "meshbay-nodew.exe") if ($LASTEXITCODE -ne 0) { throw "a frozen connection process did not carry a connection" } +# The client is frozen from its own analysis, so what the daemon's checks +# proved says nothing about it: a module PyInstaller missed fails at run time +# only. --version and `groups --help` build the parser, which imports every +# action and the client library; the self-test loads what the parser does not +# -- the interactive mode drawn off-screen (Textual, Rich), keyring's backends +# (Windows Credential Manager), an aiortc offer. The CLI has the node's version +# (all packages share one). +Step "smoke test: meshbay-cli" +$cli = Join-Path $OutDir "meshbay-cli.exe" +$out = (& $cli --version 2>&1) -join "`n" +if ($LASTEXITCODE -ne 0 -or $out -notmatch "meshbay-cli $expect") { + throw "frozen meshbay-cli --version exited $LASTEXITCODE`n$out" +} +$out = (& $cli groups --help 2>&1) -join "`n" +if ($LASTEXITCODE -ne 0 -or $out -notmatch "List the groups") { + throw "frozen meshbay-cli groups --help exited $LASTEXITCODE`n$out" +} +$env:MESHBAY_CLI_SELFTEST = "1" +try { $out = (& $cli 2>&1) -join "`n" } finally { Remove-Item Env:MESHBAY_CLI_SELFTEST } +if ($LASTEXITCODE -ne 0 -or $out -notmatch "self-test ok") { + throw "frozen meshbay-cli self-test exited $LASTEXITCODE`n$out" +} + if ($createdVenv -and -not $KeepBuildVenv) { Remove-Item -Recurse -Force $BuildVenv -ErrorAction SilentlyContinue } |