116 lines
5.4 KiB
PHP
116 lines
5.4 KiB
PHP
<?php
|
|
|
|
namespace App\Console\Commands;
|
|
|
|
use Illuminate\Console\Command;
|
|
use Illuminate\Support\Facades\Artisan;
|
|
use Illuminate\Support\Facades\Cache;
|
|
|
|
class AppInstallUpdateCommand extends Command
|
|
{
|
|
protected $signature = 'app:install-update {--tag= : Bestimmten Git-Tag installieren}';
|
|
protected $description = 'Installiert das neueste Update vom Gitea-Repository';
|
|
|
|
public function handle(): int
|
|
{
|
|
$projectPath = base_path();
|
|
|
|
$this->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}");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|