info(''); $this->info('╔══════════════════════════════════════╗'); $this->info('║ Network-MGMT Update ║'); $this->info('╚══════════════════════════════════════╝'); $this->info(''); // ── 1. Tags holen ────────────────────────────────────────────────────── $this->info('▶ Git: Aktuelle Tags holen ...'); $this->exec("cd {$projectPath} && git fetch --tags 2>&1"); // ── 2. Ziel-Tag bestimmen ────────────────────────────────────────────── if ($this->option('tag')) { $targetTag = $this->option('tag'); } else { $targetTag = trim(shell_exec( "cd {$projectPath} && git describe --tags \$(git rev-list --tags --max-count=1) 2>/dev/null" )); } if (empty($targetTag)) { $this->error('Kein Release-Tag im Repository gefunden.'); return Command::FAILURE; } $currentVersion = config('version.current'); $this->info(" Aktuell: {$currentVersion}"); $this->info(" Ziel: {$targetTag}"); $this->info(''); if ($targetTag === $currentVersion) { $this->warn('Bereits auf der neuesten Version. Abbruch.'); return Command::SUCCESS; } // ── 3. Wartungsmodus ─────────────────────────────────────────────────── $this->info('▶ Wartungsmodus aktivieren ...'); Artisan::call('down', ['--render' => 'errors.maintenance']); try { // ── 4. Git Checkout ──────────────────────────────────────────────── $this->info("▶ Git: Checkout {$targetTag} ..."); $this->exec("cd {$projectPath} && git checkout {$targetTag} 2>&1"); // ── 5. Composer ──────────────────────────────────────────────────── $this->info('▶ Composer: Abhängigkeiten aktualisieren ...'); $this->exec("cd {$projectPath} && composer install --no-dev --optimize-autoloader --no-interaction 2>&1"); // ── 6. Assets ────────────────────────────────────────────────────── if (file_exists("{$projectPath}/package.json")) { $this->info('▶ Node: Assets neu bauen ...'); $this->exec("cd {$projectPath} && npm ci --silent 2>&1"); $this->exec("cd {$projectPath} && npm run build 2>&1"); } // ── 7. Migrationen ───────────────────────────────────────────────── $this->info('▶ Datenbank: Migrationen ausführen ...'); Artisan::call('migrate', ['--force' => true, '--no-interaction' => true]); $this->line(Artisan::output()); // ── 8. Cache leeren und neu aufbauen ─────────────────────────────── $this->info('▶ Cache: Neu aufbauen ...'); Artisan::call('config:cache'); Artisan::call('route:cache'); Artisan::call('view:cache'); // ── 9. Update-Cache zurücksetzen ─────────────────────────────────── Cache::forget('app_update_available'); Cache::forget('app_update_checked_at'); $this->info(''); $this->info("✓ Update auf {$targetTag} erfolgreich abgeschlossen!"); } catch (\Throwable $e) { $this->error('Update fehlgeschlagen: ' . $e->getMessage()); Artisan::call('up'); return Command::FAILURE; } finally { // ── 10. Wartungsmodus deaktivieren ───────────────────────────────── $this->info('▶ Wartungsmodus deaktivieren ...'); Artisan::call('up'); } return Command::SUCCESS; } private function exec(string $cmd): void { $output = shell_exec($cmd); if ($output) { foreach (explode("\n", trim($output)) as $line) { if (trim($line)) { $this->line(" {$line}"); } } } } }