From 978fad64f4822d4e8de1a182426bc718ddd7c48e Mon Sep 17 00:00:00 2001 From: boban Date: Mon, 27 Apr 2026 01:12:08 +0200 Subject: [PATCH] =?UTF-8?q?Fix:=20CheckUpdates=20nutzt=20version=5Fraw=20a?= =?UTF-8?q?ls=20prim=C3=A4re=20Installationsversion=20+=20git=20fetch=20al?= =?UTF-8?q?s=20Fallback?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Sonnet 4.6 --- app/Console/Commands/CheckUpdates.php | 52 ++++++++++++++++----------- 1 file changed, 32 insertions(+), 20 deletions(-) diff --git a/app/Console/Commands/CheckUpdates.php b/app/Console/Commands/CheckUpdates.php index 41bc3d5..a56f531 100644 --- a/app/Console/Commands/CheckUpdates.php +++ b/app/Console/Commands/CheckUpdates.php @@ -7,7 +7,7 @@ use Illuminate\Console\Command; class CheckUpdates extends Command { protected $signature = 'clubird:check-updates'; - protected $description = 'Check for newer MailWolt releases via git tags'; + protected $description = 'Check for newer CluBird releases via git tags'; public function handle(): int { @@ -16,22 +16,28 @@ class CheckUpdates extends Command $appPath = base_path(); - // www-data hat keine git-Credentials für private Repos. - // Fallback-Kette (erste funktionierende Methode gewinnt): - // 1. mailwolt-update --check-only (verfügbar wenn update.sh neu genug, sudoers: mailwolt-update) - // 2. mailwolt-fetch-tags (verfügbar ab v1.1.268) - // Sicherheitscheck: --check-only nur aufrufen wenn das Skript das Flag auch kennt. + // Fallback-Kette für Remote-Tags (erste funktionierende Methode gewinnt): + // 1. mailwolt-update --check-only (sudoers: mailwolt-update) + // 2. mailwolt-fetch-tags (sudoers: mailwolt-fetch-tags) + // 3. git fetch --tags als App-User direkt $updateBin = '/usr/local/sbin/mailwolt-update'; $fetchHelper = '/usr/local/sbin/mailwolt-fetch-tags'; - // --check-only via exec() (shell_exec kann auf manchen Servern deaktiviert sein) $fetched = false; + if (file_exists($updateBin) && str_contains((string) @file_get_contents($updateBin), '--check-only')) { @exec('sudo -n ' . escapeshellarg($updateBin) . ' --check-only 2>/dev/null', $_, $rc); $fetched = ($rc === 0); } + if (!$fetched && file_exists($fetchHelper)) { - @exec('sudo -n ' . escapeshellarg($fetchHelper) . ' 2>/dev/null'); + @exec('sudo -n ' . escapeshellarg($fetchHelper) . ' 2>/dev/null', $_, $rc); + $fetched = ($rc === 0); + } + + // Direkter git fetch als Fallback (klappt wenn Credentials im Repo hinterlegt sind) + if (!$fetched) { + @exec('git -C ' . escapeshellarg($appPath) . ' fetch --tags origin 2>/dev/null', $_, $rc); } // version_remote von Helfer geschrieben; als frisch wenn < 2h alt @@ -41,33 +47,30 @@ class CheckUpdates extends Command $remoteRaw = trim((string) file_get_contents($remoteFile)); } - // Fallback: lokale Tags (funktioniert nur wenn Tags lokal vorhanden) + // Lokale Tags (nach fetch hoffentlich aktuell) $out = []; @exec("git -C " . escapeshellarg($appPath) . " tag -l 'v*' --sort=-v:refname 2>/dev/null", $out); $latestTagRaw = $remoteRaw !== '' ? $remoteRaw : trim($out[0] ?? ''); $latestNorm = $this->normalizeVersion($latestTagRaw); - // Nichts gefunden -> alles leeren if (!$latestNorm) { cache()->forget('updates:latest'); cache()->forget('updates:latest_raw'); - cache()->forget('mailwolt.update_available'); // legacy + cache()->forget('mailwolt.update_available'); $this->warn('Keine Release-Tags gefunden.'); return self::SUCCESS; } - // Nur wenn wirklich neuer als installiert -> Keys setzen if ($currentNorm && version_compare($latestNorm, $currentNorm, '>')) { cache()->forever('updates:latest', $latestNorm); cache()->forever('updates:latest_raw', $latestTagRaw ?: ('v'.$latestNorm)); - cache()->forever('mailwolt.update_available', $latestNorm); // legacy-kompat + cache()->forever('mailwolt.update_available', $latestNorm); $this->info("Update verfügbar: {$latestTagRaw} (installiert: ".($currentRaw ?? $currentNorm).")"); } else { - // Kein Update -> Keys löschen cache()->forget('updates:latest'); cache()->forget('updates:latest_raw'); - cache()->forget('mailwolt.update_available'); // legacy + cache()->forget('mailwolt.update_available'); $this->info("Aktuell (installiert: ".($currentRaw ?? $currentNorm ?? 'unbekannt').")."); } @@ -79,13 +82,22 @@ class CheckUpdates extends Command private function readInstalledVersionNorm(): ?string { + // version_raw ist die zuverlässigste Quelle – wird vom Update-Script geschrieben + $rawVer = $this->normalizeVersion($this->readInstalledVersionRaw() ?? ''); + $fileVer = null; foreach (['/var/lib/mailwolt/version', base_path('VERSION')] as $p) { $raw = @trim(@file_get_contents($p) ?: ''); if ($raw !== '') { $fileVer = $this->normalizeVersion($raw); break; } } - // git-Tag bevorzugen wenn neuer (Dev-Server hat oft veraltete Versionsdatei) + // version_raw bevorzugen (echter installierter Stand) + // Nur wenn version_raw fehlt: version-Datei oder git-Tag als Fallback + if ($rawVer) { + return $rawVer; + } + + // git-Tag als letzter Fallback (funktioniert auf Dev-Servern) $out = []; @exec('git -C ' . escapeshellarg(base_path()) . ' describe --tags --abbrev=0 2>/dev/null', $out); $gitVer = $this->normalizeVersion(trim($out[0] ?? '')); @@ -93,12 +105,12 @@ class CheckUpdates extends Command if ($gitVer && (!$fileVer || version_compare($gitVer, $fileVer, '>'))) { return $gitVer; } - return $fileVer ?: $this->normalizeVersion($this->readInstalledVersionRaw() ?? ''); + return $fileVer ?: null; } private function readInstalledVersionRaw(): ?string { - $p = '/var/lib/mailwolt/version_raw'; // vom Wrapper (z.B. "v1.0.25" oder "v1.0.25-3-gabcd") + $p = '/var/lib/mailwolt/version_raw'; $raw = @trim(@file_get_contents($p) ?: ''); return $raw !== '' ? $raw : null; } @@ -108,8 +120,8 @@ class CheckUpdates extends Command if (!$v) return null; $v = trim($v); if ($v === '') return null; - $v = ltrim($v, "vV \t\n\r\0\x0B"); // führendes v entfernen - $v = preg_replace('/-.*$/', '', $v); // Build-/dirty-Suffix abschneiden + $v = ltrim($v, "vV \t\n\r\0\x0B"); + $v = preg_replace('/-.*$/', '', $v); return $v !== '' ? $v : null; } }