aboutsummaryrefslogtreecommitdiffstats
path: root/packaging/build/build-client.sh
diff options
context:
space:
mode:
authorChristophe Besson <cbesson@gmail.com>2026-08-31 10:49:45 +0200
committerChristophe Besson <cbesson@gmail.com>2026-08-31 10:49:45 +0200
commit8d5c564e75ad2928e77ea66decc979366ca5ccd5 (patch)
tree7f88ceb2ccd838011bb2f399f148c7f9b39f75ec /packaging/build/build-client.sh
parent0c2754d2d4cb1905d5e324f56fbc64e4afae526f (diff)
downloadmeshbay-8d5c564e75ad2928e77ea66decc979366ca5ccd5.tar.gz
feat(packaging): 4-package .deb/.rpm build system under /opt
Shared venv architecture: meshbay-common owns the Python venv with all pip deps pre-installed; hub and node add only their code into it. Client is a standalone Electron app. No pip runs at install time. - Add build scripts (packaging/build/) for common, hub, node, client - Add orchestrator build-packages.sh with deb/rpm auto-detection - Add .deb control/postinst for all 4 packages - Add .rpm specs for all 4 packages (replaces python3-meshbay-common) - Add Gnome .desktop launcher and icon resizing - Add firewalld services (meshbay-cast, meshbay-node) and UFW profiles - Update systemd units to use /opt/meshbay-common/venv/bin/ paths - TMDB token baked into node package at build time via QE/node.env - Fix package-lock.json sync for protobufjs override Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Diffstat (limited to 'packaging/build/build-client.sh')
-rwxr-xr-xpackaging/build/build-client.sh116
1 files changed, 116 insertions, 0 deletions
diff --git a/packaging/build/build-client.sh b/packaging/build/build-client.sh
new file mode 100755
index 0000000..fbdf51e
--- /dev/null
+++ b/packaging/build/build-client.sh
@@ -0,0 +1,116 @@
+#!/usr/bin/env bash
+# Build the meshbay-client package: Electron app + .desktop launcher.
+#
+# Usage: ./build-client.sh [staging-dir] [--arm64]
+#
+# Requires Node >= 22. If not in PATH, set NODEJS_DIR=/opt/nodejs or similar.
+set -euo pipefail
+
+REPO="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
+STAGING="${1:-/tmp/meshbay-build}"
+ROOT="$STAGING/meshbay-client-root"
+CLIENT="$REPO/packages/meshbay-client"
+
+ARCH_FLAG=""
+ELECTRON_ARCH="x64"
+DEB_ARCH="amd64"
+for arg in "$@"; do
+ if [ "$arg" = "--arm64" ]; then
+ ARCH_FLAG="--arm64"
+ ELECTRON_ARCH="arm64"
+ DEB_ARCH="arm64"
+ fi
+done
+
+# Node.js version check
+if [ -n "${NODEJS_DIR:-}" ]; then
+ export PATH="$NODEJS_DIR/bin:$PATH"
+fi
+NODE_VER=$(node --version 2>/dev/null || echo "none")
+echo "==> meshbay-client (Node $NODE_VER, arch=$ELECTRON_ARCH)"
+
+if ! node --version >/dev/null 2>&1; then
+ echo "!! Node.js not found. Set NODEJS_DIR or install Node >= 22." >&2
+ exit 1
+fi
+
+NODE_MAJOR=$(node -e "process.stdout.write(String(process.versions.node.split('.')[0]))")
+if [ "$NODE_MAJOR" -lt 22 ]; then
+ echo "!! Node $NODE_VER is too old — need >= 22 for Electron" >&2
+ exit 1
+fi
+
+rm -rf "$ROOT"
+mkdir -p "$ROOT"
+
+# --- Build the Electron app -----------------------------------------------
+cd "$CLIENT"
+
+echo " npm ci"
+npm ci --ignore-scripts 2>&1 | tail -3
+
+echo " approving + installing electron"
+npm approve-scripts electron 2>/dev/null || true
+node node_modules/electron/install.js 2>&1 | tail -1
+
+echo " syncing UI from hub package"
+npm run sync-ui 2>&1 | tail -1
+
+echo " electron-builder --dir $ARCH_FLAG"
+npx electron-builder --dir --linux $ARCH_FLAG 2>&1 | tail -5
+
+# Determine the unpacked output directory
+if [ "$ELECTRON_ARCH" = "arm64" ]; then
+ UNPACKED="$CLIENT/dist/linux-arm64-unpacked"
+else
+ UNPACKED="$CLIENT/dist/linux-unpacked"
+fi
+
+[ -d "$UNPACKED" ] || { echo "!! electron-builder output not found at $UNPACKED" >&2; exit 1; }
+
+# --- Assemble the package tree --------------------------------------------
+echo " assembling /opt/meshbay-client/"
+mkdir -p "$ROOT/opt/meshbay-client"
+cp -a "$UNPACKED"/* "$ROOT/opt/meshbay-client/"
+
+# Rename the electron binary
+if [ -f "$ROOT/opt/meshbay-client/meshbay-client" ]; then
+ mv "$ROOT/opt/meshbay-client/meshbay-client" "$ROOT/opt/meshbay-client/meshbay"
+elif [ -f "$ROOT/opt/meshbay-client/electron" ]; then
+ mv "$ROOT/opt/meshbay-client/electron" "$ROOT/opt/meshbay-client/meshbay"
+fi
+
+# Symlink in PATH
+mkdir -p "$ROOT/usr/bin"
+ln -sf /opt/meshbay-client/meshbay "$ROOT/usr/bin/meshbay"
+
+# --- Desktop launcher -----------------------------------------------------
+mkdir -p "$ROOT/usr/share/applications"
+cp "$REPO/packaging/desktop/meshbay.desktop" "$ROOT/usr/share/applications/"
+
+# --- Icons ----------------------------------------------------------------
+ICON_SRC="$CLIENT/build/icon.png"
+if [ -f "$ICON_SRC" ]; then
+ for size in 128 256 512; do
+ ICON_DIR="$ROOT/usr/share/icons/hicolor/${size}x${size}/apps"
+ mkdir -p "$ICON_DIR"
+ if command -v convert >/dev/null 2>&1; then
+ convert "$ICON_SRC" -resize "${size}x${size}" "$ICON_DIR/meshbay.png"
+ elif command -v magick >/dev/null 2>&1; then
+ magick "$ICON_SRC" -resize "${size}x${size}" "$ICON_DIR/meshbay.png"
+ else
+ # Fallback: copy the original at all sizes (better than no icon)
+ cp "$ICON_SRC" "$ICON_DIR/meshbay.png"
+ fi
+ done
+ echo " icons installed"
+else
+ echo " !! icon.png not found at $ICON_SRC — no icons" >&2
+fi
+
+# --- Firewall profile (Chromecast) ----------------------------------------
+mkdir -p "$ROOT/usr/lib/firewalld/services"
+cp "$REPO/packaging/firewall/firewalld/meshbay-cast.xml" \
+ "$ROOT/usr/lib/firewalld/services/"
+
+echo "==> meshbay-client staging ready at $ROOT ($DEB_ARCH)"