get()) { return; } try { if (! is_dir($repoPath.'/.git')) { Log::warning("Next.js repo push skipped (no .git): {$repoPath}"); return; } $remote = (string) config('services.nextjs.repo_remote', 'origin'); $branch = (string) config('services.nextjs.repo_branch', 'main'); // Keep the repo up to date to reduce push failures. static::run($repoPath, ['git', 'fetch', $remote]); static::run($repoPath, ['git', 'checkout', $branch]); static::run($repoPath, ['git', 'pull', '--rebase', $remote, $branch]); // Only stage asset directories we manage. static::run($repoPath, ['git', 'add', '-A', '--', 'public/uploads', 'public/images']); $status = static::run($repoPath, ['git', 'status', '--porcelain']); if (trim($status) === '') { return; } $msg = (string) config('services.nextjs.repo_assets_commit_message', 'chore(assets): sync public assets'); $msg .= ' ('.now()->format('Y-m-d H:i:s').')'; static::run($repoPath, ['git', 'commit', '-m', $msg]); static::run($repoPath, ['git', 'push', $remote, $branch]); } catch (\Throwable $e) { Log::warning('Next.js repo push failed: '.$e->getMessage()); } finally { $lock->release(); } } public static function scheduleAssetsPush(): void { if (! config('services.nextjs.autopush_assets')) { return; } // If queue is sync, this runs inline; otherwise requires a worker. \App\Jobs\PushNextjsPublicAssetsJob::dispatch()->delay(now()->addSeconds(5)); } private static function resolveRepoRoot(): ?string { $configured = config('services.nextjs.repo_path'); if (is_string($configured) && $configured !== '' && is_dir($configured)) { return $configured; } $public = config('services.nextjs.public_path'); if (is_string($public) && $public !== '') { $root = dirname($public); if (is_dir($root)) { return $root; } } $guess = base_path('../usher-site'); if (is_dir($guess)) { return $guess; } return null; } private static function run(string $cwd, array $cmd): string { $p = new Process($cmd, $cwd); $p->setTimeout(60); $p->run(); $out = (string) $p->getOutput(); $err = (string) $p->getErrorOutput(); if (! $p->isSuccessful()) { throw new \RuntimeException('Command failed: '.implode(' ', $cmd)."\n".$err.$out); } return $out.$err; } }