updates
This commit is contained in:
@@ -20,12 +20,20 @@ class Deploy extends Component
|
|||||||
protected array $command = [];
|
protected array $command = [];
|
||||||
protected $source;
|
protected $source;
|
||||||
|
|
||||||
|
protected $listeners = [
|
||||||
|
'applicationStatusChanged' => 'applicationStatusChanged',
|
||||||
|
];
|
||||||
|
|
||||||
public function mount()
|
public function mount()
|
||||||
{
|
{
|
||||||
$this->parameters = get_parameters();
|
$this->parameters = get_parameters();
|
||||||
$this->application = Application::where('id', $this->applicationId)->first();
|
$this->application = Application::where('id', $this->applicationId)->first();
|
||||||
$this->destination = $this->application->destination->getMorphClass()::where('id', $this->application->destination->id)->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()
|
protected function set_deployment_uuid()
|
||||||
{
|
{
|
||||||
// Create Deployment ID
|
// Create Deployment ID
|
||||||
|
@@ -3,16 +3,17 @@
|
|||||||
namespace App\Http\Livewire\Project\Application;
|
namespace App\Http\Livewire\Project\Application;
|
||||||
|
|
||||||
use App\Enums\ActivityTypes;
|
use App\Enums\ActivityTypes;
|
||||||
|
use App\Models\Application;
|
||||||
use Illuminate\Support\Facades\Redis;
|
use Illuminate\Support\Facades\Redis;
|
||||||
use Livewire\Component;
|
use Livewire\Component;
|
||||||
use Spatie\Activitylog\Models\Activity;
|
use Spatie\Activitylog\Models\Activity;
|
||||||
|
|
||||||
class DeploymentLogs extends Component
|
class DeploymentLogs extends Component
|
||||||
{
|
{
|
||||||
|
public Application $application;
|
||||||
public $activity;
|
public $activity;
|
||||||
public $isKeepAliveOn = true;
|
public $isKeepAliveOn = true;
|
||||||
public $deployment_uuid;
|
public $deployment_uuid;
|
||||||
|
|
||||||
public function polling()
|
public function polling()
|
||||||
{
|
{
|
||||||
if (is_null($this->activity) && isset($this->deployment_uuid)) {
|
if (is_null($this->activity) && isset($this->deployment_uuid)) {
|
||||||
|
@@ -6,9 +6,8 @@ use App\Enums\ProcessStatus;
|
|||||||
use App\Models\Application;
|
use App\Models\Application;
|
||||||
use App\Models\ApplicationDeploymentQueue;
|
use App\Models\ApplicationDeploymentQueue;
|
||||||
use Livewire\Component;
|
use Livewire\Component;
|
||||||
use Spatie\Activitylog\Contracts\Activity;
|
|
||||||
|
|
||||||
class DeploymentCancel extends Component
|
class DeploymentNavbar extends Component
|
||||||
{
|
{
|
||||||
public Application $application;
|
public Application $application;
|
||||||
public $activity;
|
public $activity;
|
||||||
@@ -16,17 +15,23 @@ class DeploymentCancel extends Component
|
|||||||
public function cancel()
|
public function cancel()
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
ray('Cancelling deployment: ' . $this->deployment_uuid . 'of application: ' . $this->application->uuid);
|
ray('Cancelling deployment: ' . $this->deployment_uuid . ' of application: ' . $this->application->uuid);
|
||||||
$deployment = ApplicationDeploymentQueue::where('deployment_uuid', $this->deployment_uuid)->firstOrFail();
|
|
||||||
$deployment->status = 'cancelled';
|
// Update deployment queue
|
||||||
|
$deployment = ApplicationDeploymentQueue::where('deployment_uuid', $this->deployment_uuid)->first();
|
||||||
|
$deployment->status = 'cancelled by user';
|
||||||
$deployment->save();
|
$deployment->save();
|
||||||
|
|
||||||
|
// Update activity
|
||||||
$this->activity->properties = $this->activity->properties->merge([
|
$this->activity->properties = $this->activity->properties->merge([
|
||||||
'exitCode' => 1,
|
'exitCode' => 1,
|
||||||
'status' => ProcessStatus::CANCELLED->value,
|
'status' => ProcessStatus::CANCELLED->value,
|
||||||
]);
|
]);
|
||||||
$this->activity->save();
|
$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) {
|
} catch (\Throwable $th) {
|
||||||
return general_error_handler($th, $this);
|
return general_error_handler($th, $this);
|
||||||
}
|
}
|
@@ -9,11 +9,9 @@ class Status extends Component
|
|||||||
{
|
{
|
||||||
public Application $application;
|
public Application $application;
|
||||||
|
|
||||||
protected $listeners = [
|
public function applicationStatusChanged()
|
||||||
'applicationStatusChanged' => 'pollingStatus',
|
|
||||||
];
|
|
||||||
public function pollingStatus()
|
|
||||||
{
|
{
|
||||||
|
$this->emit('applicationStatusChanged');
|
||||||
$this->application->refresh();
|
$this->application->refresh();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -50,8 +50,8 @@ class ApplicationDeploymentJob implements ShouldQueue
|
|||||||
public string $deployment_uuid,
|
public string $deployment_uuid,
|
||||||
public string $application_id,
|
public string $application_id,
|
||||||
public bool $force_rebuild = false,
|
public bool $force_rebuild = false,
|
||||||
public string|null $rollback_commit = null,
|
public string $rollback_commit = 'HEAD',
|
||||||
public string|null $pull_request_id = null,
|
public int $pull_request_id = 0,
|
||||||
) {
|
) {
|
||||||
$this->application_deployment_queue = ApplicationDeploymentQueue::find($this->application_deployment_queue_id);
|
$this->application_deployment_queue = ApplicationDeploymentQueue::find($this->application_deployment_queue_id);
|
||||||
$this->application_deployment_queue->update([
|
$this->application_deployment_queue->update([
|
||||||
@@ -104,8 +104,6 @@ class ApplicationDeploymentJob implements ShouldQueue
|
|||||||
$this->deploy();
|
$this->deploy();
|
||||||
}
|
}
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
ray('Oops something is not okay, are you okay? 😢');
|
|
||||||
ray($e);
|
|
||||||
$this->execute_now([
|
$this->execute_now([
|
||||||
"echo '\nOops something is not okay, are you okay? 😢'",
|
"echo '\nOops something is not okay, are you okay? 😢'",
|
||||||
"echo '\n\n{$e->getMessage()}'",
|
"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}...'",
|
"echo 'Starting deployment of {$this->application->git_repository}:{$this->application->git_branch}...'",
|
||||||
]);
|
]);
|
||||||
$this->start_builder_image();
|
$this->start_builder_image();
|
||||||
|
ray('Rollback Commit: ' . $this->rollback_commit);
|
||||||
if ($this->rollback_commit === 'HEAD') {
|
if ($this->rollback_commit === 'HEAD') {
|
||||||
$this->clone_repository();
|
$this->clone_repository();
|
||||||
}
|
}
|
||||||
@@ -265,35 +264,24 @@ COPY --from=$this->build_image_name /app/{$this->application->publish_directory}
|
|||||||
|
|
||||||
public function failed(): void
|
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->next(ProcessStatus::ERROR->value);
|
||||||
$this->fail();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private function next(string $status)
|
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(
|
dispatch(new ContainerStatusJob(
|
||||||
application: $this->application,
|
application: $this->application,
|
||||||
container_name: $this->container_name,
|
container_name: $this->container_name,
|
||||||
pull_request_id: $this->pull_request_id
|
pull_request_id: $this->pull_request_id
|
||||||
));
|
));
|
||||||
$this->application_deployment_queue->update([
|
|
||||||
'status' => $status,
|
queue_next_deployment($this->application);
|
||||||
]);
|
|
||||||
$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,
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
private function execute_in_builder(string $command)
|
private function execute_in_builder(string $command)
|
||||||
{
|
{
|
||||||
@@ -534,7 +522,7 @@ COPY --from=$this->build_image_name /app/{$this->application->publish_directory}
|
|||||||
} else {
|
} else {
|
||||||
$commandText = collect($command)->implode("\n");
|
$commandText = collect($command)->implode("\n");
|
||||||
}
|
}
|
||||||
|
ray('Executing command', $commandText);
|
||||||
$this->activity->properties = $this->activity->properties->merge([
|
$this->activity->properties = $this->activity->properties->merge([
|
||||||
'command' => $commandText,
|
'command' => $commandText,
|
||||||
]);
|
]);
|
||||||
@@ -665,8 +653,5 @@ COPY --from=$this->build_image_name /app/{$this->application->publish_directory}
|
|||||||
$this->execute_now([
|
$this->execute_now([
|
||||||
$this->execute_in_builder("echo '{$docker_compose_base64}' | base64 -d > {$this->workdir}/docker-compose.yml")
|
$this->execute_in_builder("echo '{$docker_compose_base64}' | base64 -d > {$this->workdir}/docker-compose.yml")
|
||||||
], hideFromOutput: true);
|
], hideFromOutput: true);
|
||||||
$this->execute_now([
|
|
||||||
"echo 'Done.'",
|
|
||||||
]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,11 +1,11 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
use App\Jobs\ApplicationDeploymentJob;
|
use App\Jobs\ApplicationDeploymentJob;
|
||||||
|
use App\Models\Application;
|
||||||
use App\Models\ApplicationDeploymentQueue;
|
use App\Models\ApplicationDeploymentQueue;
|
||||||
|
|
||||||
function queue_application_deployment(int $application_id, string $deployment_uuid, int|null $pull_request_id = 0, string $commit = 'HEAD', bool $force_rebuild = false, bool $is_webhook = false)
|
function queue_application_deployment(int $application_id, string $deployment_uuid, int|null $pull_request_id = 0, string $commit = 'HEAD', bool $force_rebuild = false, bool $is_webhook = false)
|
||||||
{
|
{
|
||||||
ray('Queuing deployment: ' . $deployment_uuid . ' of applicationID: ' . $application_id . ' pull request: ' . $pull_request_id . ' with commit: ' . $commit . ' and is it forced: ' . $force_rebuild);
|
|
||||||
$deployment = ApplicationDeploymentQueue::create([
|
$deployment = ApplicationDeploymentQueue::create([
|
||||||
'application_id' => $application_id,
|
'application_id' => $application_id,
|
||||||
'deployment_uuid' => $deployment_uuid,
|
'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');
|
$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');
|
$running_deployments = ApplicationDeploymentQueue::where('application_id', $application_id)->where('status', 'in_progress')->get()->sortByDesc('created_at');
|
||||||
ray('Queued deployments: ' . $queued_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);
|
||||||
ray('Running deployments: ' . $running_deployments->count());
|
|
||||||
if ($queued_deployments->count() > 1) {
|
if ($queued_deployments->count() > 1) {
|
||||||
$queued_deployments = $queued_deployments->skip(1);
|
$queued_deployments = $queued_deployments->skip(1);
|
||||||
$queued_deployments->each(function ($queued_deployment, $key) {
|
$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,
|
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,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -7,6 +7,7 @@ use App\Models\Server;
|
|||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
use Illuminate\Support\Facades\Process;
|
use Illuminate\Support\Facades\Process;
|
||||||
use Illuminate\Support\Facades\Storage;
|
use Illuminate\Support\Facades\Storage;
|
||||||
|
use Illuminate\Support\Sleep;
|
||||||
use Spatie\Activitylog\Models\Activity;
|
use Spatie\Activitylog\Models\Activity;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -76,7 +77,7 @@ function generate_ssh_command(string $private_key_location, string $server_ip, s
|
|||||||
return $ssh_command;
|
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);
|
$command_string = implode("\n", $command);
|
||||||
$private_key_location = save_private_key_for_server($server);
|
$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());
|
$output = trim($process->output());
|
||||||
$exitCode = $process->exitCode();
|
$exitCode = $process->exitCode();
|
||||||
if ($exitCode !== 0) {
|
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());
|
ray($process->errorOutput());
|
||||||
if (!$throwError) {
|
if (!$throwError) {
|
||||||
return null;
|
return null;
|
||||||
|
@@ -1,3 +0,0 @@
|
|||||||
<div>
|
|
||||||
<x-forms.button wire:click="cancel" isHighlighted>Cancel</x-forms.button>
|
|
||||||
</div>
|
|
@@ -1,4 +1,10 @@
|
|||||||
<div
|
<div>
|
||||||
|
<div class="pt-2 text-sm">Build status: {{ data_get($activity, 'properties.status') }}</div>
|
||||||
|
@if (data_get($activity, 'properties.status') === 'in_progress')
|
||||||
|
<livewire:project.application.deployment-navbar :activity="$activity" :application="$application" :deployment_uuid="$deployment_uuid" />
|
||||||
|
@endif
|
||||||
|
<div
|
||||||
class="scrollbar flex flex-col-reverse w-full overflow-y-auto border border-solid rounded border-coolgray-300 max-h-[32rem] p-4 mt-4 text-xs text-white">
|
class="scrollbar flex flex-col-reverse w-full overflow-y-auto border border-solid rounded border-coolgray-300 max-h-[32rem] p-4 mt-4 text-xs text-white">
|
||||||
<pre class="font-mono whitespace-pre-wrap" @if ($isKeepAliveOn) wire:poll.2000ms="polling" @endif>{{ \App\Actions\CoolifyTask\RunRemoteProcess::decodeOutput($activity) }}</pre>
|
<pre class="font-mono whitespace-pre-wrap" @if ($isKeepAliveOn) wire:poll.2000ms="polling" @endif>{{ \App\Actions\CoolifyTask\RunRemoteProcess::decodeOutput($activity) }}</pre>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@@ -0,0 +1,3 @@
|
|||||||
|
<div>
|
||||||
|
<x-forms.button wire:click.prevent="cancel">Cancel deployment</x-forms.button>
|
||||||
|
</div>
|
@@ -1,4 +1,4 @@
|
|||||||
<div wire:poll.5000ms='pollingStatus'>
|
<div wire:poll.5000ms='applicationStatusChanged'>
|
||||||
@if ($application->status === 'running')
|
@if ($application->status === 'running')
|
||||||
<span class="text-xs text-pink-600" wire:loading.delay.longer>Loading current status...</span>
|
<span class="text-xs text-pink-600" wire:loading.delay.longer>Loading current status...</span>
|
||||||
<div class="flex items-center gap-2 text-sm" wire:loading.remove.delay.longer>
|
<div class="flex items-center gap-2 text-sm" wire:loading.remove.delay.longer>
|
||||||
|
@@ -12,11 +12,8 @@
|
|||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<x-applications.navbar :application="$application" />
|
<x-applications.navbar :application="$application" />
|
||||||
<div class="pt-2 text-sm">Status: {{ data_get($activity, 'properties.status') }}</div>
|
{{-- @if (data_get($activity, 'properties.status') === 'in_progress' && (data_get($deployment, 'metadata.status') !== 'error' || data_get($deployment, 'metadata.status') !== 'finished'))
|
||||||
@if (data_get($activity, 'properties.status') === 'in_progress' &&
|
|
||||||
(data_get($deployment, 'metadata.status') !== 'error' ||
|
|
||||||
data_get($deployment, 'metadata.status') !== 'finished'))
|
|
||||||
<livewire:project.application.deployment-cancel :activity="$activity" :application="$application" :deployment_uuid="$deployment_uuid" />
|
<livewire:project.application.deployment-cancel :activity="$activity" :application="$application" :deployment_uuid="$deployment_uuid" />
|
||||||
@endif
|
@endif --}}
|
||||||
<livewire:project.application.deployment-logs :activity="$activity" :deployment_uuid="$deployment_uuid" />
|
<livewire:project.application.deployment-logs :activity="$activity" :application="$application" :deployment_uuid="$deployment_uuid" />
|
||||||
</x-layout>
|
</x-layout>
|
||||||
|
Reference in New Issue
Block a user