Erste Version
holt die Sourcen aus dem Signal-Desktop GIT Repo und baut das RPM. Voraussetzung: Nodejs24 installiert.
This commit is contained in:
parent
7f6ccc6ce5
commit
ec6a8b463b
1 changed files with 193 additions and 0 deletions
193
update-signal.sh
Normal file
193
update-signal.sh
Normal 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"
|
||||
Loading…
Add table
Reference in a new issue