public handle ( App\Repositories\Project\ProjectInterface $projectRepository, App\Repositories\Server\ServerInterface $serverRepository, Symfony\Component\Process\ProcessBuilder $processBuilder, App\Services\Notification\NotifierInterface $notifier, App\Repositories\Setting\SettingInterface $settingRepository ) : void | ||
$projectRepository | App\Repositories\Project\ProjectInterface | |
$serverRepository | App\Repositories\Server\ServerInterface | |
$processBuilder | Symfony\Component\Process\ProcessBuilder | |
$notifier | App\Services\Notification\NotifierInterface | |
$settingRepository | App\Repositories\Setting\SettingInterface | |
리턴 | 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('deploy')->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);
}
}
public function test_Should_WorkAndSendNotification_When_DeployerIsAbnormalEndAndEmailNotificationRecipientIsSet() { $deployment = Factory::build('App\\Models\\Deployment', ['id' => 1, 'project_id' => 1, 'number' => 1, 'task' => 'deploy', 'user_id' => 1, 'created_at' => new \Carbon\Carbon(), 'updated_at' => new \Carbon\Carbon(), 'user' => new \App\Models\User()]); $updatedDeployment = Factory::build('App\\Models\\Deployment', ['id' => 1, 'project_id' => 1, 'number' => 1, 'task' => 'deploy', 'user_id' => 1, 'created_at' => new \Carbon\Carbon(), 'updated_at' => new \Carbon\Carbon(), 'user' => new \App\Models\User(), 'stauts' => 1]); $recipe = Factory::build('App\\Models\\Recipe', ['id' => 1, 'name' => 'Recipe 1', 'desctiption' => '', 'body' => '']); $project = $this->mockProjectModel->shouldReceive('updateDeployment')->once()->shouldReceive('getDeploymentByNumber')->once()->andReturn($updatedDeployment)->mock(); $project = $this->mockProjectModel->shouldReceive('getRecipes')->once()->andReturn([$recipe])->mock(); $project->email_notification_recipient = '*****@*****.**'; $this->mockProjectRepository->shouldReceive('byId')->once()->andReturn($project); $this->mockServerRepository->shouldReceive('byId')->once()->andReturn($this->mockServerModel); $mockDeployerFile = $this->mock('App\\Services\\Deployment\\DeployerFile')->shouldReceive('getFullPath')->once()->mock(); $this->mockDeployerFileDirector->shouldReceive('construct')->andReturn($mockDeployerFile)->times(3); $this->mockProcess->shouldReceive('run')->once(); $this->mockProcess->shouldReceive('isSuccessful')->twice()->andReturn(false); $this->mockProcess->shouldReceive('getErrorOutput')->once(); $this->mockProcess->shouldReceive('getExitCode')->once(); $this->mockProcessBuilder->shouldReceive('add')->times(7)->andReturn($this->mockProcessBuilder); $this->mockProcessBuilder->shouldReceive('getProcess')->once()->andReturn($this->mockProcess); $this->mockNotifier->shouldReceive('to')->once()->andReturn($this->mockNotifier); $this->mockNotifier->shouldReceive('notify')->once(); $this->mockMailSettingEntity->shouldReceive('getDriver')->once()->shouldReceive('getFrom')->twice()->shouldReceive('getSmtpHost')->once()->shouldReceive('getSmtpPort')->once()->shouldReceive('getSmtpEncryption')->once()->shouldReceive('getSmtpUsername')->once()->shouldReceive('getSmtpPassword')->once()->shouldReceive('getSendmailPath')->once(); $this->mockSettingModel->shouldReceive('getAttribute')->with('attributes')->andReturn($this->mockMailSettingEntity); $this->mockSettingRepositroy->shouldReceive('byType')->once()->andReturn($this->mockSettingModel); $this->mockServerListFileBuilder->shouldReceive('setServer')->once()->andReturn($this->mockServerListFileBuilder); $this->mockServerListFileBuilder->shouldReceive('setProject')->once()->andReturn($this->mockServerListFileBuilder); $this->mockRecipeFileBuilder->shouldReceive('setRecipe')->once(); $this->mockDeploymentFileBuilder->shouldReceive('setProject')->once()->andReturn($this->mockDeploymentFileBuilder); $this->mockDeploymentFileBuilder->shouldReceive('setServerListFile')->once()->andReturn($this->mockDeploymentFileBuilder); $this->mockDeploymentFileBuilder->shouldReceive('setRecipeFile')->once()->andReturn($this->mockDeploymentFileBuilder); $job = new Deploy($deployment); $job->handle($this->mockProjectRepository, $this->mockServerRepository, $this->mockProcessBuilder, $this->mockNotifier, $this->mockSettingRepositroy); }