diff --git a/update-signal.sh b/update-signal.sh new file mode 100644 index 0000000..b51cf00 --- /dev/null +++ b/update-signal.sh @@ -0,0 +1,193 @@ +#!/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"