Erste Version

holt die Sourcen aus dem Signal-Desktop GIT Repo und baut das RPM.
Voraussetzung: Nodejs24 installiert.
This commit is contained in:
fds2610 2026-07-27 19:38:31 +02:00
parent 7f6ccc6ce5
commit ec6a8b463b

193
update-signal.sh Normal file
View file

@ -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<major>.<minor>.<patch> 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/tty || answer=''
case "$answer" in [jJyY]*) ;; *) die "Abgebrochen." ;; esac
fi
fi
fi
# /usr/bin/pnpm hat #!/usr/bin/node fest im Shebang und würde den Shim umgehen,
# deshalb pnpm explizit mit dem gewählten Interpreter starten.
pnpm() { "${NODE_RUN[@]}" "$PNPM_BIN" "$@"; }
echo "Build läuft mit Node $(node -v), pnpm $(pnpm -v)"
# --- Bauen --------------------------------------------------------------------
rm -f release/*.rpm # alte Artefakte weg, damit das Ergebnis eindeutig ist
info "Installiere npm-Abhängigkeiten (pnpm install)"
# confirmModulesPurge=false: stammen die vorhandenen node_modules von einer anderen
# pnpm-/Node-Version, will pnpm sie löschen und fragt vorher nach – ohne TTY (Hintergrund,
# CI) bricht es sonst mit ERR_PNPM_ABORTED_REMOVE_MODULES_DIR_NO_TTY ab.
pnpm install --config.confirmModulesPurge=false
info "Baue Signal $VERSION – das dauert etwa 20 Minuten"
pnpm run clean-transpile
pnpm run generate
pnpm run prepare-beta-build # No-op bei stabilen Versionen, nötig für Beta-Tags
pnpm run build-linux
# Dateiname folgt artifactName "${name}_${version}_${arch}.${ext}", daher per Glob suchen.
RPM="$(find release -maxdepth 1 -name '*.rpm' -print -quit)"
[ -n "$RPM" ] || die "Kein RPM in $SRC_DIR/release gefunden – der Build ist fehlgeschlagen."
# --- Installieren -------------------------------------------------------------
# Der Install-Schritt braucht root. Läuft das Skript ohne Terminal (z. B. im Hintergrund)
# und ist sudo nicht passwortfrei, wird hier abgebrochen statt an der Passwortabfrage
# hängen zu bleiben – das fertige RPM bleibt liegen und kann von Hand installiert werden.
if [ "$INSTALLED" = "$VERSION" ]; then DNF_ACTION='reinstall'; else DNF_ACTION='install'; fi
if [ "$BUILD_ONLY" -eq 1 ] || { [ ! -t 0 ] && ! "$SUDO" -n true 2>/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"