#!/usr/bin/env bash # Build the Linux artifacts (AppImage + .deb) WITHOUT Docker and WITHOUT # recompiling the Rust launcher. # # WHY: this app's launcher (Tauri/Rust) barely ever changes — what changes is the # cockpit itself (web/ JSX), which ships as a *resource* the Bun sidecar serves at # runtime. So a release is really just: rebuild the web cockpit, drop it into the # already-compiled bundle, and repack. That's seconds, not a Docker cross-build. # # It reuses three things produced by a prior full `tauri build`: # * the compiled launcher + GTK/WebKit libs in the AppDir # * the cached linuxdeploy appimage packer (~/.cache/tauri/...) # * the seed .deb (for its control metadata + file tree) # and refreshes the cockpit (usr/lib/X-Plane Cockpit/web) + Lua plugins in both. # # Seed once (native, no Docker) if the AppDir is missing: # scripts/prep-desktop.sh # npx --prefix desktop tauri build --target x86_64-unknown-linux-gnu --bundles appimage,deb # Thereafter just run this script for every web-only change. # # CAVEAT: the launcher binary is reused as-is, so the *version it reports itself* # (used by the auto-updater) is whatever it was last compiled with — not # necessarily $VERSION. The cockpit features are unaffected (they come from the # refreshed web resources). If you bump the version AND rely on the updater, # recompile the launcher once with the tauri build line above. set -euo pipefail ROOT="$(cd "$(dirname "$0")/.." && pwd)"; cd "$ROOT" die(){ echo "!! $*" >&2; exit 1; } TARGET=x86_64-unknown-linux-gnu BUNDLE="$ROOT/target-linux/$TARGET/release/bundle" APPDIR="$BUNDLE/appimage/X-Plane Cockpit.AppDir" RESDIR="$APPDIR/usr/lib/X-Plane Cockpit" PLUGIN="$HOME/.cache/tauri/linuxdeploy-plugin-appimage.AppImage" SIDECAR="$ROOT/desktop/src-tauri/binaries/xpbridge-$TARGET" PKGNAME="X-Plane Cockpit" VERSION="$(node -p "require('$ROOT/desktop/src-tauri/tauri.conf.json').version")" echo "==> X-Plane Cockpit Linux repack — v$VERSION (no Docker, no Rust recompile)" # ---- preflight ----------------------------------------------------------- [[ -d "$APPDIR" ]] || die "no prebuilt AppDir: $APPDIR — seed one full tauri build first (see header)" [[ -x "$PLUGIN" ]] || die "missing appimage packer: $PLUGIN — run one tauri appimage build to fetch it" [[ -f "$SIDECAR" ]] || die "missing sidecar: $SIDECAR — run scripts/prep-desktop.sh" command -v ar >/dev/null || die "'ar' (binutils) required to assemble the .deb" command -v tar >/dev/null || die "'tar' required" SIGN=0 [[ -f desktop/.tauri-signing.key && -f desktop/.tauri-signing.pw ]] && SIGN=1 sign(){ # $1 = artifact; writes .sig next to it if [[ $SIGN == 1 ]]; then TAURI_SIGNING_PRIVATE_KEY="$(cat desktop/.tauri-signing.key)" \ TAURI_SIGNING_PRIVATE_KEY_PASSWORD="$(cat desktop/.tauri-signing.pw)" \ npx --prefix desktop tauri signer sign "$1" >/dev/null echo " signed: $(basename "$1").sig" else rm -f "$1.sig" fi } # ---- 1. build the web cockpit, refresh repo resources -------------------- echo "==> building web cockpit (vite)" ( cd web && npm run build >/dev/null ) echo "==> refreshing desktop/src-tauri/resources" rm -rf "desktop/src-tauri/resources/web"; mkdir -p "desktop/src-tauri/resources/web" cp -R web/dist/. "desktop/src-tauri/resources/web/" rm -rf "desktop/src-tauri/resources/plugins"; mkdir -p "desktop/src-tauri/resources/plugins" cp plugins/*.lua "desktop/src-tauri/resources/plugins/" # ---- 2. refresh the cockpit inside the prebuilt AppDir ------------------- echo "==> updating bundled cockpit inside AppDir" rm -rf "$RESDIR/web"; mkdir -p "$RESDIR/web"; cp -R web/dist/. "$RESDIR/web/" rm -rf "$RESDIR/plugins"; mkdir -p "$RESDIR/plugins"; cp plugins/*.lua "$RESDIR/plugins/" # the AppDir's sidecar copy may be a patchelf-corrupted one — restore the pristine cp -f "$SIDECAR" "$APPDIR/usr/bin/xpbridge"; chmod +x "$APPDIR/usr/bin/xpbridge" # ---- 3. pack the AppImage (cached linuxdeploy plugin, no patchelf) ------- OUTIMG="$BUNDLE/appimage/${PKGNAME}_${VERSION}_amd64.AppImage" echo "==> packing AppImage -> $(basename "$OUTIMG")" rm -f "$OUTIMG" APPIMAGE_EXTRACT_AND_RUN=1 NO_STRIP=1 ARCH=x86_64 LDAI_OUTPUT="$OUTIMG" \ "$PLUGIN" --appdir "$APPDIR" >/dev/null [[ -f "$OUTIMG" ]] || die "AppImage packing produced nothing" chmod +x "$OUTIMG" sign "$OUTIMG" echo " AppImage: $(du -h "$OUTIMG" | cut -f1)" # The .deb is intentionally NOT built: the AppImage is the single self-contained, # self-updating artifact (the Tauri Linux updater swaps the AppImage in place; it # never uses a .deb). If you ever want a .deb too, run a full native tauri build # with --bundles appimage,deb. echo "==> done. artifact:" ls -1 "$OUTIMG"