- Add docker volume prune to deploy.sh to prevent stale code issues - Add automatic migrations and cache warmup to staging entrypoint - Fix nginx race condition by waiting for PHP-FPM before starting - Improve PHP healthcheck to use php-fpm-healthcheck - Add curl to production nginx Dockerfile for healthchecks - Add ensureSeedsTable() to SeedRepository for automatic table creation - Update SeedCommand to ensure seeds table exists before operations This prevents 502 Bad Gateway errors during deployment and ensures fresh code is deployed without volume cache issues.
76 lines
1.9 KiB
PHP
76 lines
1.9 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Framework\Database\Seed;
|
|
|
|
use App\Framework\Logging\Logger;
|
|
|
|
final readonly class SeedRunner
|
|
{
|
|
public function __construct(
|
|
private SeedRepository $seedRepository,
|
|
private ?Logger $logger = null
|
|
) {
|
|
}
|
|
|
|
/**
|
|
* Run a seeder if it hasn't been executed yet
|
|
*
|
|
* @param Seeder $seeder The seeder to run
|
|
* @throws \Throwable If the seeder fails
|
|
*/
|
|
public function run(Seeder $seeder): void
|
|
{
|
|
$name = $seeder->getName();
|
|
|
|
// Check if already executed
|
|
if ($this->seedRepository->hasRun($name)) {
|
|
$this->log("Skipping seeder '{$name}' - already executed", 'info');
|
|
|
|
return;
|
|
}
|
|
|
|
$this->log("Running seeder '{$name}'...", 'info');
|
|
|
|
try {
|
|
$seeder->seed();
|
|
$this->seedRepository->markAsRun($name, $seeder->getDescription());
|
|
$this->log("Seeder '{$name}' completed successfully", 'info');
|
|
} catch (\Throwable $e) {
|
|
$this->log("Seeder '{$name}' failed: {$e->getMessage()}", 'error');
|
|
|
|
throw $e;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Run multiple seeders
|
|
*
|
|
* @param Seeder[] $seeders Array of seeders to run
|
|
*/
|
|
public function runAll(array $seeders): void
|
|
{
|
|
foreach ($seeders as $seeder) {
|
|
$this->run($seeder);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Log a message if logger is available
|
|
*/
|
|
private function log(string $message, string $level = 'info'): void
|
|
{
|
|
if ($this->logger !== null) {
|
|
match ($level) {
|
|
'error' => $this->logger->error($message),
|
|
'warning' => $this->logger->warning($message),
|
|
default => $this->logger->info($message),
|
|
};
|
|
} else {
|
|
// Fallback to echo if no logger available
|
|
echo "[{$level}] {$message}\n";
|
|
}
|
|
}
|
|
}
|