diff --git a/app/Http/Livewire/Project/Application/Deploy.php b/app/Http/Livewire/Project/Application/Deploy.php index b7c221a5d..c8b06bf4b 100644 --- a/app/Http/Livewire/Project/Application/Deploy.php +++ b/app/Http/Livewire/Project/Application/Deploy.php @@ -20,12 +20,20 @@ class Deploy extends Component protected array $command = []; protected $source; + protected $listeners = [ + 'applicationStatusChanged' => 'applicationStatusChanged', + ]; + public function mount() { $this->parameters = get_parameters(); $this->application = Application::where('id', $this->applicationId)->first(); $this->destination = $this->application->destination->getMorphClass()::where('id', $this->application->destination->id)->first(); } + public function applicationStatusChanged() + { + $this->application->refresh(); + } protected function set_deployment_uuid() { // Create Deployment ID diff --git a/app/Http/Livewire/Project/Application/DeploymentLogs.php b/app/Http/Livewire/Project/Application/DeploymentLogs.php index fc7d9e7c0..cd13909ef 100644 --- a/app/Http/Livewire/Project/Application/DeploymentLogs.php +++ b/app/Http/Livewire/Project/Application/DeploymentLogs.php @@ -3,16 +3,17 @@ namespace App\Http\Livewire\Project\Application; use App\Enums\ActivityTypes; +use App\Models\Application; use Illuminate\Support\Facades\Redis; use Livewire\Component; use Spatie\Activitylog\Models\Activity; class DeploymentLogs extends Component { + public Application $application; public $activity; public $isKeepAliveOn = true; public $deployment_uuid; - public function polling() { if (is_null($this->activity) && isset($this->deployment_uuid)) { diff --git a/app/Http/Livewire/Project/Application/DeploymentCancel.php b/app/Http/Livewire/Project/Application/DeploymentNavbar.php similarity index 70% rename from app/Http/Livewire/Project/Application/DeploymentCancel.php rename to app/Http/Livewire/Project/Application/DeploymentNavbar.php index 24e587023..4bc91a0a1 100644 --- a/app/Http/Livewire/Project/Application/DeploymentCancel.php +++ b/app/Http/Livewire/Project/Application/DeploymentNavbar.php @@ -6,9 +6,8 @@ use App\Enums\ProcessStatus; use App\Models\Application; use App\Models\ApplicationDeploymentQueue; use Livewire\Component; -use Spatie\Activitylog\Contracts\Activity; -class DeploymentCancel extends Component +class DeploymentNavbar extends Component { public Application $application; public $activity; @@ -16,17 +15,23 @@ class DeploymentCancel extends Component public function cancel() { try { - ray('Cancelling deployment: ' . $this->deployment_uuid . 'of application: ' . $this->application->uuid); - $deployment = ApplicationDeploymentQueue::where('deployment_uuid', $this->deployment_uuid)->firstOrFail(); - $deployment->status = 'cancelled'; + ray('Cancelling deployment: ' . $this->deployment_uuid . ' of application: ' . $this->application->uuid); + + // Update deployment queue + $deployment = ApplicationDeploymentQueue::where('deployment_uuid', $this->deployment_uuid)->first(); + $deployment->status = 'cancelled by user'; $deployment->save(); + + // Update activity $this->activity->properties = $this->activity->properties->merge([ 'exitCode' => 1, 'status' => ProcessStatus::CANCELLED->value, ]); $this->activity->save(); - instant_remote_process(["docker rm -f {$this->deployment_uuid}"], $this->application->destination->server, throwError: false); + // Remove builder container + instant_remote_process(["docker rm -f {$this->deployment_uuid}"], $this->application->destination->server, throwError: false, repeat: 25); + queue_next_deployment($this->application); } catch (\Throwable $th) { return general_error_handler($th, $this); } diff --git a/app/Http/Livewire/Project/Application/Status.php b/app/Http/Livewire/Project/Application/Status.php index a326d7c38..34a33b348 100644 --- a/app/Http/Livewire/Project/Application/Status.php +++ b/app/Http/Livewire/Project/Application/Status.php @@ -9,11 +9,9 @@ class Status extends Component { public Application $application; - protected $listeners = [ - 'applicationStatusChanged' => 'pollingStatus', - ]; - public function pollingStatus() + public function applicationStatusChanged() { + $this->emit('applicationStatusChanged'); $this->application->refresh(); } } diff --git a/app/Jobs/ApplicationDeploymentJob.php b/app/Jobs/ApplicationDeploymentJob.php index 934ec70e9..655d4b620 100644 --- a/app/Jobs/ApplicationDeploymentJob.php +++ b/app/Jobs/ApplicationDeploymentJob.php @@ -50,8 +50,8 @@ class ApplicationDeploymentJob implements ShouldQueue public string $deployment_uuid, public string $application_id, public bool $force_rebuild = false, - public string|null $rollback_commit = null, - public string|null $pull_request_id = null, + public string $rollback_commit = 'HEAD', + public int $pull_request_id = 0, ) { $this->application_deployment_queue = ApplicationDeploymentQueue::find($this->application_deployment_queue_id); $this->application_deployment_queue->update([ @@ -104,8 +104,6 @@ class ApplicationDeploymentJob implements ShouldQueue $this->deploy(); } } catch (\Exception $e) { - ray('Oops something is not okay, are you okay? 😢'); - ray($e); $this->execute_now([ "echo '\nOops something is not okay, are you okay? 😢'", "echo '\n\n{$e->getMessage()}'", @@ -230,6 +228,7 @@ COPY --from=$this->build_image_name /app/{$this->application->publish_directory} "echo 'Starting deployment of {$this->application->git_repository}:{$this->application->git_branch}...'", ]); $this->start_builder_image(); + ray('Rollback Commit: ' . $this->rollback_commit); if ($this->rollback_commit === 'HEAD') { $this->clone_repository(); } @@ -265,35 +264,24 @@ COPY --from=$this->build_image_name /app/{$this->application->publish_directory} public function failed(): void { - ray('failed job'); - $this->activity->properties = $this->activity->properties->merge([ - 'exitCode' => 1, - 'status' => ProcessStatus::ERROR->value, - ]); - $this->activity->save(); $this->next(ProcessStatus::ERROR->value); - $this->fail(); } private function next(string $status) { + ray($this->application_deployment_queue->status, Str::of($this->application_deployment_queue->status)->startsWith('cancelled')); + if (!Str::of($this->application_deployment_queue->status)->startsWith('cancelled')) { + $this->application_deployment_queue->update([ + 'status' => $status, + ]); + } dispatch(new ContainerStatusJob( application: $this->application, container_name: $this->container_name, pull_request_id: $this->pull_request_id )); - $this->application_deployment_queue->update([ - 'status' => $status, - ]); - $next_found = ApplicationDeploymentQueue::where('application_id', $this->application->id)->where('status', 'queued')->first(); - if ($next_found) { - dispatch(new ApplicationDeploymentJob( - application_deployment_queue_id: $next_found->id, - application_id: $next_found->application_id, - deployment_uuid: $next_found->deployment_uuid, - force_rebuild: $next_found->force_rebuild, - )); - } + + queue_next_deployment($this->application); } private function execute_in_builder(string $command) { @@ -534,7 +522,7 @@ COPY --from=$this->build_image_name /app/{$this->application->publish_directory} } else { $commandText = collect($command)->implode("\n"); } - + ray('Executing command', $commandText); $this->activity->properties = $this->activity->properties->merge([ 'command' => $commandText, ]); @@ -665,8 +653,5 @@ COPY --from=$this->build_image_name /app/{$this->application->publish_directory} $this->execute_now([ $this->execute_in_builder("echo '{$docker_compose_base64}' | base64 -d > {$this->workdir}/docker-compose.yml") ], hideFromOutput: true); - $this->execute_now([ - "echo 'Done.'", - ]); } } diff --git a/bootstrap/helpers/applications.php b/bootstrap/helpers/applications.php index 9914bc9a9..ac65607fb 100644 --- a/bootstrap/helpers/applications.php +++ b/bootstrap/helpers/applications.php @@ -1,11 +1,11 @@ $application_id, 'deployment_uuid' => $deployment_uuid, @@ -16,8 +16,7 @@ function queue_application_deployment(int $application_id, string $deployment_uu ]); $queued_deployments = ApplicationDeploymentQueue::where('application_id', $application_id)->where('status', 'queued')->get()->sortByDesc('created_at'); $running_deployments = ApplicationDeploymentQueue::where('application_id', $application_id)->where('status', 'in_progress')->get()->sortByDesc('created_at'); - ray('Queued deployments: ' . $queued_deployments->count()); - ray('Running deployments: ' . $running_deployments->count()); + ray('Q:' . $queued_deployments->count() . 'R:' . $running_deployments->count() . '|Queuing deployment: ' . $deployment_uuid . ' of applicationID: ' . $application_id . ' pull request: ' . $pull_request_id . ' with commit: ' . $commit . ' and is it forced: ' . $force_rebuild); if ($queued_deployments->count() > 1) { $queued_deployments = $queued_deployments->skip(1); $queued_deployments->each(function ($queued_deployment, $key) { @@ -37,3 +36,16 @@ function queue_application_deployment(int $application_id, string $deployment_uu pull_request_id: $pull_request_id, )); } + +function queue_next_deployment(Application $application) +{ + $next_found = ApplicationDeploymentQueue::where('application_id', $application->id)->where('status', 'queued')->first(); + if ($next_found) { + dispatch(new ApplicationDeploymentJob( + application_deployment_queue_id: $next_found->id, + application_id: $next_found->application_id, + deployment_uuid: $next_found->deployment_uuid, + force_rebuild: $next_found->force_rebuild, + )); + } +} diff --git a/bootstrap/helpers/remoteProcess.php b/bootstrap/helpers/remoteProcess.php index 9ead36cf6..4b6fc9756 100644 --- a/bootstrap/helpers/remoteProcess.php +++ b/bootstrap/helpers/remoteProcess.php @@ -7,6 +7,7 @@ use App\Models\Server; use Illuminate\Database\Eloquent\Model; use Illuminate\Support\Facades\Process; use Illuminate\Support\Facades\Storage; +use Illuminate\Support\Sleep; use Spatie\Activitylog\Models\Activity; /** @@ -76,7 +77,7 @@ function generate_ssh_command(string $private_key_location, string $server_ip, s return $ssh_command; } -function instant_remote_process(array $command, Server $server, $throwError = true) +function instant_remote_process(array $command, Server $server, $throwError = true, $repeat = 1) { $command_string = implode("\n", $command); $private_key_location = save_private_key_for_server($server); @@ -85,6 +86,11 @@ function instant_remote_process(array $command, Server $server, $throwError = tr $output = trim($process->output()); $exitCode = $process->exitCode(); if ($exitCode !== 0) { + if ($repeat > 1) { + Sleep::for(200)->milliseconds(); + ray('executing again'); + return instant_remote_process($command, $server, $throwError, $repeat - 1); + } ray($process->errorOutput()); if (!$throwError) { return null; diff --git a/resources/views/livewire/project/application/deployment-cancel.blade.php b/resources/views/livewire/project/application/deployment-cancel.blade.php deleted file mode 100644 index c1220f8ea..000000000 --- a/resources/views/livewire/project/application/deployment-cancel.blade.php +++ /dev/null @@ -1,3 +0,0 @@ -