#!/bin/bash # Baut Signal-Desktop aus dem Quellcode und installiert es als RPM (Fedora Asahi / aarch64). # Basiert auf https://github.com/kenballus/asahi-signal-desktop, erweitert um # automatische Versionserkennung, Update-Check und wiederverwendbaren Checkout. # # Aufruf: # ./update-signal.sh # neuesten stabilen Release bauen (falls neuer als installiert) # ./update-signal.sh 8.11.0 # bestimmte Version bauen # ./update-signal.sh --force # auch bauen, wenn die Version schon installiert ist # ./update-signal.sh --deps # vorher die Build-Abhängigkeiten via dnf installieren # ./update-signal.sh --clean # node_modules/release vor dem Build löschen (bei kaputtem Build) # ./update-signal.sh --check # nur nachsehen, ob es etwas Neueres gibt # ./update-signal.sh --build-only # nur bauen, Installation (braucht root) überspringen set -euo pipefail SRC_DIR="$HOME/Signal-Desktop" REPO_URL="https://github.com/signalapp/Signal-Desktop" PKG_NAME="signal-desktop" VERSION="" FORCE=0 INSTALL_DEPS=0 CLEAN=0 CHECK_ONLY=0 BUILD_ONLY=0 for arg in "$@"; do case "$arg" in --force) FORCE=1 ;; --deps) INSTALL_DEPS=1 ;; --clean) CLEAN=1 ;; --check) CHECK_ONLY=1 ;; --build-only) BUILD_ONLY=1 ;; -h|--help) sed -n '2,12p' "$0"; exit 0 ;; -*) echo "Unbekannte Option: $arg" >&2; exit 1 ;; *) VERSION="${arg#v}" ;; esac done info() { printf '\n\033[1;34m==>\033[0m \033[1m%s\033[0m\n' "$*"; } warn() { printf '\033[1;33mWarnung:\033[0m %s\n' "$*" >&2; } die() { printf '\033[1;31mFehler:\033[0m %s\n' "$*" >&2; exit 1; } if [ -x /usr/bin/sudo ]; then SUDO='sudo'; else SUDO='doas'; fi # --- Build-Abhängigkeiten (nur auf Wunsch) ----------------------------------- if [ "$INSTALL_DEPS" -eq 1 ]; then info "Installiere Build-Abhängigkeiten" "$SUDO" dnf install -y g++ npm python3 make gcc git rpm-build libxcrypt-compat patch ruby-devel pnpm command -v fpm >/dev/null || gem install --user-install fpm fi export PATH="$PATH:$HOME/bin" export USE_SYSTEM_FPM=true SIGNAL_ENV=production for tool in git pnpm node fpm rpmbuild; do command -v "$tool" >/dev/null || die "'$tool' fehlt. Einmalig mit './update-signal.sh --deps' nachinstallieren." done # --- Quellcode holen / aktualisieren ----------------------------------------- if [ ! -d "$SRC_DIR/.git" ]; then info "Klone $REPO_URL nach $SRC_DIR" git clone "$REPO_URL" "$SRC_DIR" fi cd "$SRC_DIR" info "Hole aktuelle Tags von upstream" git fetch --tags --force --prune origin main # --- Zielversion bestimmen ---------------------------------------------------- if [ -z "$VERSION" ]; then # Nur echte Releases: v.. ohne -alpha/-beta/-adhoc-Suffix. VERSION="$(git tag -l 'v*' --sort=-v:refname \ | grep -E '^v[0-9]+\.[0-9]+\.[0-9]+$' \ | head -1)" VERSION="${VERSION#v}" [ -n "$VERSION" ] || die "Konnte keinen stabilen Release-Tag ermitteln." fi git rev-parse --verify "v$VERSION^{tag}" >/dev/null 2>&1 \ || die "Tag 'v$VERSION' existiert nicht im Repository." INSTALLED="$(rpm -q --qf '%{VERSION}' "$PKG_NAME" 2>/dev/null || echo 'keine')" echo "Installiert: $INSTALLED | Ziel: $VERSION" if [ "$CHECK_ONLY" -eq 1 ]; then [ "$INSTALLED" = "$VERSION" ] && echo "Signal ist aktuell." || echo "Update verfügbar: $INSTALLED -> $VERSION" exit 0 fi if [ "$INSTALLED" = "$VERSION" ] && [ "$FORCE" -eq 0 ]; then info "Version $VERSION ist bereits installiert – nichts zu tun (--force erzwingt den Neubau)." exit 0 fi FREE_GB="$(df -BG --output=avail "$HOME" | tail -1 | tr -dc '0-9')" [ "$FREE_GB" -lt 15 ] && warn "Nur ${FREE_GB} GB frei in \$HOME – der Build braucht rund 10–15 GB." # --- Auschecken und für RPM patchen ------------------------------------------- info "Checke v$VERSION aus" git reset --hard --quiet # eigenen package.json-Patch vom letzten Lauf verwerfen git checkout --quiet "v$VERSION" if [ "$CLEAN" -eq 1 ]; then info "Räume node_modules und release auf" rm -rf node_modules release fi # electron-builder soll ein RPM für diese Architektur erzeugen statt eines DEB für x64. # Upstream hat das Format von build.linux.target mehrfach geändert (mal ["deb"], mal # [{"target":"deb","arch":"x64"}]), deshalb wird der Wert per JSON gesetzt statt per sed. case "$(uname -m)" in aarch64) EB_ARCH='arm64' ;; x86_64) EB_ARCH='x64' ;; *) die "Unbekannte Architektur $(uname -m)." ;; esac node -e ' const fs = require("fs"); const pkg = JSON.parse(fs.readFileSync("package.json", "utf8")); if (!pkg.build || !pkg.build.linux) throw new Error("build.linux fehlt in package.json"); pkg.build.linux.target = [{ target: "rpm", arch: process.argv[1] }]; fs.writeFileSync("package.json", JSON.stringify(pkg, null, 2) + "\n"); ' "$EB_ARCH" || die "package.json konnte nicht auf das RPM-Target gepatcht werden." echo "Build-Target: rpm/$EB_ARCH" # Passende Node-Version wählen. Fedora installiert parallele Versionen als # /usr/bin/node-22, /usr/bin/node-24 usw.; /usr/bin/node ist nur ein Symlink auf die # Standardversion. Statt diesen systemweit umzuhängen, wird für den Build ein Shim- # Verzeichnis an den Anfang von PATH gesetzt. PNPM_BIN="$(command -v pnpm)" NODE_RUN=(node) if [ -f .nvmrc ]; then WANT_NODE="$(tr -dc '0-9.' < .nvmrc)"; WANT_NODE="${WANT_NODE%%.*}" HAVE_NODE="$(node -v | tr -d 'v')"; HAVE_NODE="${HAVE_NODE%%.*}" if [ "$WANT_NODE" != "$HAVE_NODE" ]; then if [ -x "/usr/bin/node-$WANT_NODE" ]; then SHIM_DIR="$(mktemp -d)" trap 'rm -rf "$SHIM_DIR"' EXIT ln -s "/usr/bin/node-$WANT_NODE" "$SHIM_DIR/node" [ -e "/usr/bin/npm-$WANT_NODE" ] && ln -s "/usr/bin/npm-$WANT_NODE" "$SHIM_DIR/npm" export PATH="$SHIM_DIR:$PATH" echo "Node $WANT_NODE via /usr/bin/node-$WANT_NODE (nur für diesen Build, System bleibt auf $HAVE_NODE)" else warn "Signal erwartet Node ${WANT_NODE}.x, aktiv ist ${HAVE_NODE}.x, und /usr/bin/node-$WANT_NODE fehlt." warn "Abhilfe: sudo dnf install nodejs$WANT_NODE nodejs$WANT_NODE-npm" printf 'Trotzdem mit Node %s fortfahren? [j/N] ' "$HAVE_NODE" read -r answer /dev/null; }; then info "Build fertig, Installation übersprungen" echo "Paket: $SRC_DIR/$RPM" echo "Installieren mit:" echo " $SUDO dnf $DNF_ACTION -y '$SRC_DIR/$RPM'" exit 0 fi info "Installiere $RPM" "$SUDO" dnf "$DNF_ACTION" -y "./$RPM" info "Fertig: $(rpm -q "$PKG_NAME")" echo "Der Checkout bleibt in $SRC_DIR liegen, damit der nächste Build schneller ist." echo "Zum Freigeben von Speicherplatz: rm -rf $SRC_DIR/node_modules $SRC_DIR/release"