/**
* Execute the job.
*
* @param \App\Repositories\Project\ProjectInterface $projectRepository
* @param \App\Repositories\Server\ServerInterface $serverRepository
* @param \Symfony\Component\Process\ProcessBuilder $processBuilder
* @param \App\Services\Notification\NotifierInterface $notifier
* @param \App\Repositories\Setting\SettingInterface $settingRepository
* @return void
*/
public function handle(ProjectInterface $projectRepository, ServerInterface $serverRepository, ProcessBuilder $processBuilder, NotifierInterface $notifier, SettingInterface $settingRepository)
{
$deployment = $this->deployment;
$project = $projectRepository->byId($deployment->project_id);
$server = $serverRepository->byId($project->server_id);
$app = app();
// Create a server list file
$serverListFileBuilder = $app->make('App\\Services\\Deployment\\DeployerServerListFileBuilder')->setServer($server)->setProject($project);
$serverListFile = $app->make('App\\Services\\Deployment\\DeployerFileDirector', [$serverListFileBuilder])->construct();
// Create recipe files
foreach ($project->getRecipes() as $i => $recipe) {
// HACK: If an instance of DeployerRecipeFileBuilder class is not stored in an array, a destructor is called and a recipe file is deleted immediately.
$recipeFileBuilders[] = $app->make('App\\Services\\Deployment\\DeployerRecipeFileBuilder')->setRecipe($recipe);
$recipeFiles[] = $app->make('App\\Services\\Deployment\\DeployerFileDirector', [$recipeFileBuilders[$i]])->construct();
}
// Create a deployment file
$deploymentFileBuilder = $app->make('App\\Services\\Deployment\\DeployerDeploymentFileBuilder')->setProject($project)->setServerListFile($serverListFile)->setRecipeFile($recipeFiles);
$deploymentFile = $app->make('App\\Services\\Deployment\\DeployerFileDirector', [$deploymentFileBuilder])->construct();
// Create a command
$processBuilder->add($this->executable)->add("-f={$deploymentFile->getFullPath()}")->add('--ansi')->add('-n')->add('-vv')->add('rollback')->add($project->stage);
// Run the command
$tmp['id'] = $deployment->id;
$tmp['message'] = '';
$process = $processBuilder->getProcess();
$process->setTimeout(600);
$process->run(function ($type, $buffer) use(&$tmp, $project, $deployment) {
$tmp['message'] .= $buffer;
$tmp['number'] = $deployment->number;
$project->updateDeployment($tmp);
});
// Store the result
if ($process->isSuccessful()) {
$message = $process->getOutput();
} else {
$message = $process->getErrorOutput();
}
$data['id'] = $deployment->id;
$data['number'] = $deployment->number;
$data['message'] = $message;
$data['status'] = $process->getExitCode();
$project->updateDeployment($data);
// Notify
if (isset($project->email_notification_recipient)) {
$mailSettings = $settingRepository->byType('mail');
if (isset($mailSettings->attributes->getFrom()['address'])) {
$fromAddress = $mailSettings->attributes->getFrom()['address'];
} else {
$fromAddress = null;
}
if (isset($mailSettings->attributes->getFrom()['name'])) {
$fromName = $mailSettings->attributes->getFrom()['name'];
} else {
$fromName = null;
}
config(['mail.driver' => $mailSettings->attributes->getDriver()]);
config(['mail.from.address' => $fromAddress]);
config(['mail.from.name' => $fromName]);
config(['mail.host' => $mailSettings->attributes->getSmtpHost()]);
config(['mail.port' => $mailSettings->attributes->getSmtpPort()]);
config(['mail.encryption' => $mailSettings->attributes->getSmtpEncryption()]);
config(['mail.username' => $mailSettings->attributes->getSmtpUsername()]);
config(['mail.password' => $mailSettings->attributes->getSmtpPassword()]);
config(['mail.sendmail' => $mailSettings->attributes->getSendmailPath()]);
$deployment = $project->getDeploymentByNumber($deployment->number);
if ($process->isSuccessful()) {
$status = 'success';
} else {
$status = 'failure';
}
$subject = "Deployment of {$project->name} #{$deployment->number} finished: {$status}";
$message = view('emails.notification')->with('project', $project)->with('deployment', $deployment)->render();
$notifier->to($project->email_notification_recipient)->notify($subject, $message);
}
}