diff --git a/app/Http/Controllers/Api/Deploy.php b/app/Http/Controllers/Api/Deploy.php index 322d73e67..04fc9b816 100644 --- a/app/Http/Controllers/Api/Deploy.php +++ b/app/Http/Controllers/Api/Deploy.php @@ -73,12 +73,17 @@ class Deploy extends Controller $message->push("Tag {$tag} not found."); continue; } - $resources = $found_tag->resources()->get(); - if ($resources->count() === 0) { + $applications = $found_tag->applications(); + $services = $found_tag->services(); + if ($applications->count() === 0 && $services->count() === 0) { $message->push("No resources found for tag {$tag}."); continue; } - foreach ($resources as $resource) { + foreach ($applications as $resource) { + $return_message = $this->deploy_resource($resource, $force); + $message = $message->merge($return_message); + } + foreach ($services as $resource) { $return_message = $this->deploy_resource($resource, $force); $message = $message->merge($return_message); } diff --git a/app/Jobs/ApplicationDeploymentJob.php b/app/Jobs/ApplicationDeploymentJob.php index 93dad8e8a..022368548 100644 --- a/app/Jobs/ApplicationDeploymentJob.php +++ b/app/Jobs/ApplicationDeploymentJob.php @@ -166,10 +166,6 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted public function handle(): void { - $this->application_deployment_queue->update([ - 'status' => ApplicationDeploymentStatus::IN_PROGRESS->value, - ]); - // Generate custom host<->ip mapping $allContainers = instant_remote_process(["docker network inspect {$this->destination->network} -f '{{json .Containers}}' "], $this->server); if (!is_null($allContainers)) { diff --git a/app/Livewire/Project/CloneMe.php b/app/Livewire/Project/CloneMe.php index 993c9516c..29cf0bea8 100644 --- a/app/Livewire/Project/CloneMe.php +++ b/app/Livewire/Project/CloneMe.php @@ -22,12 +22,12 @@ class CloneMe extends Component public ?int $selectedDestination = null; public ?Server $server = null; public $resources = []; - public string $newProjectName = ''; + public string $newName = ''; protected $messages = [ 'selectedServer' => 'Please select a server.', 'selectedDestination' => 'Please select a server & destination.', - 'newProjectName' => 'Please enter a name for the new project.', + 'newName' => 'Please enter a name for the new project or environment.', ]; public function mount($project_uuid) { @@ -36,7 +36,7 @@ class CloneMe extends Component $this->environment = $this->project->environments->where('name', $this->environment_name)->first(); $this->project_id = $this->project->id; $this->servers = currentTeam()->servers; - $this->newProjectName = str($this->project->name . '-clone-' . (string)new Cuid2(7))->slug(); + $this->newName = str($this->project->name . '-clone-' . (string)new Cuid2(7))->slug(); } public function render() @@ -46,34 +46,50 @@ class CloneMe extends Component public function selectServer($server_id, $destination_id) { + if ($server_id == $this->selectedServer && $destination_id == $this->selectedDestination) { + $this->selectedServer = null; + $this->selectedDestination = null; + $this->server = null; + return; + } $this->selectedServer = $server_id; $this->selectedDestination = $destination_id; $this->server = $this->servers->where('id', $server_id)->first(); } - public function clone() + public function clone(string $type) { try { $this->validate([ 'selectedDestination' => 'required', - 'newProjectName' => 'required', + 'newName' => 'required', ]); - $foundProject = Project::where('name', $this->newProjectName)->first(); - if ($foundProject) { - throw new \Exception('Project with the same name already exists.'); - } - $newProject = Project::create([ - 'name' => $this->newProjectName, - 'team_id' => currentTeam()->id, - 'description' => $this->project->description . ' (clone)', - ]); - if ($this->environment->name !== 'production') { - $newProject->environments()->create([ - 'name' => $this->environment->name, + if ($type === 'project') { + $foundProject = Project::where('name', $this->newName)->first(); + if ($foundProject) { + throw new \Exception('Project with the same name already exists.'); + } + $project = Project::create([ + 'name' => $this->newName, + 'team_id' => currentTeam()->id, + 'description' => $this->project->description . ' (clone)', + ]); + if ($this->environment->name !== 'production') { + $project->environments()->create([ + 'name' => $this->environment->name, + ]); + } + $environment = $project->environments->where('name', $this->environment->name)->first(); + } else { + $foundEnv = $this->project->environments()->where('name', $this->newName)->first(); + if ($foundEnv) { + throw new \Exception('Environment with the same name already exists.'); + } + $project = $this->project; + $environment = $this->project->environments()->create([ + 'name' => $this->newName, ]); } - $newEnvironment = $newProject->environments->where('name', $this->environment->name)->first(); - // Clone Applications $applications = $this->environment->applications; $databases = $this->environment->databases(); $services = $this->environment->services; @@ -83,7 +99,7 @@ class CloneMe extends Component 'uuid' => $uuid, 'fqdn' => generateFqdn($this->server, $uuid), 'status' => 'exited', - 'environment_id' => $newEnvironment->id, + 'environment_id' => $environment->id, // This is not correct, but we need to set it to something 'destination_id' => $this->selectedDestination, ]); @@ -110,7 +126,7 @@ class CloneMe extends Component 'uuid' => $uuid, 'status' => 'exited', 'started_at' => null, - 'environment_id' => $newEnvironment->id, + 'environment_id' => $environment->id, 'destination_id' => $this->selectedDestination, ]); $newDatabase->save(); @@ -136,7 +152,7 @@ class CloneMe extends Component $uuid = (string)new Cuid2(7); $newService = $service->replicate()->fill([ 'uuid' => $uuid, - 'environment_id' => $newEnvironment->id, + 'environment_id' => $environment->id, 'destination_id' => $this->selectedDestination, ]); $newService->save(); @@ -153,8 +169,8 @@ class CloneMe extends Component $newService->parse(); } return redirect()->route('project.resource.index', [ - 'project_uuid' => $newProject->uuid, - 'environment_name' => $newEnvironment->name, + 'project_uuid' => $project->uuid, + 'environment_name' => $environment->name, ]); } catch (\Exception $e) { return handleError($e, $this); diff --git a/app/Livewire/Project/New/GithubPrivateRepositoryDeployKey.php b/app/Livewire/Project/New/GithubPrivateRepositoryDeployKey.php index 723d4bb60..ad52b9070 100644 --- a/app/Livewire/Project/New/GithubPrivateRepositoryDeployKey.php +++ b/app/Livewire/Project/New/GithubPrivateRepositoryDeployKey.php @@ -9,6 +9,7 @@ use App\Models\PrivateKey; use App\Models\Project; use App\Models\StandaloneDocker; use App\Models\SwarmDocker; +use Illuminate\Support\Collection; use Livewire\Component; use Spatie\Url\Url; use Illuminate\Support\Str; @@ -18,7 +19,7 @@ class GithubPrivateRepositoryDeployKey extends Component public $current_step = 'private_keys'; public $parameters; public $query; - public $private_keys; + public $private_keys =[]; public int $private_key_id; public int $port = 3000; @@ -33,6 +34,11 @@ class GithubPrivateRepositoryDeployKey extends Component public $build_pack = 'nixpacks'; public bool $show_is_static = true; + private object $repository_url_parsed; + private GithubApp|GitlabApp|string $git_source = 'other'; + private ?string $git_host = null; + private string $git_repository; + protected $rules = [ 'repository_url' => 'required', 'branch' => 'required|string', @@ -49,10 +55,7 @@ class GithubPrivateRepositoryDeployKey extends Component 'publish_directory' => 'Publish directory', 'build_pack' => 'Build pack', ]; - private object $repository_url_parsed; - private GithubApp|GitlabApp|string $git_source = 'other'; - private ?string $git_host = null; - private string $git_repository; + public function mount() { diff --git a/app/Livewire/Project/Shared/Tags.php b/app/Livewire/Project/Shared/Tags.php index db330b15c..0977f18f8 100644 --- a/app/Livewire/Project/Shared/Tags.php +++ b/app/Livewire/Project/Shared/Tags.php @@ -37,12 +37,13 @@ class Tags extends Component return handleError($e, $this); } } - public function deleteTag($id, $name) + public function deleteTag(string $id) { try { - $found_more_tags = Tag::where(['name' => $name, 'team_id' => currentTeam()->id])->first(); $this->resource->tags()->detach($id); - if ($found_more_tags->resources()->get()->count() == 0) { + + $found_more_tags = Tag::where(['id' => $id, 'team_id' => currentTeam()->id])->first(); + if ($found_more_tags->applications()->count() == 0 && $found_more_tags->services()->count() == 0){ $found_more_tags->delete(); } $this->refresh(); @@ -53,6 +54,7 @@ class Tags extends Component public function refresh() { $this->resource->load(['tags']); + $this->tags = Tag::ownedByCurrentTeam()->get(); $this->new_tag = null; } public function submit() diff --git a/app/Livewire/Server/ShowPrivateKey.php b/app/Livewire/Server/ShowPrivateKey.php index 0834866c1..43b55fbb6 100644 --- a/app/Livewire/Server/ShowPrivateKey.php +++ b/app/Livewire/Server/ShowPrivateKey.php @@ -39,7 +39,7 @@ class ShowPrivateKey extends Component if ($uptime) { $this->dispatch('success', 'Server is reachable.'); } else { - $this->dispatch('error', 'Server is not reachable.
Please validate your configuration and connection.

Check this documentation for further help.'); + $this->dispatch('error', 'Server is not reachable.
Please validate your configuration and connection.

Check this documentation for further help.'); return; } } catch (\Throwable $e) { diff --git a/app/Livewire/Tags/Show.php b/app/Livewire/Tags/Show.php index 6a61a0851..3bb669615 100644 --- a/app/Livewire/Tags/Show.php +++ b/app/Livewire/Tags/Show.php @@ -9,15 +9,30 @@ use Livewire\Component; class Show extends Component { + public $tags; public Tag $tag; - public $resources; + public $applications; + public $services; public $webhook = null; public $deployments_per_tag_per_server = []; + public function mount() + { + $this->tags = Tag::ownedByCurrentTeam()->get()->unique('name')->sortBy('name'); + $tag = $this->tags->where('name', request()->tag_name)->first(); + if (!$tag) { + return redirect()->route('tags.index'); + } + $this->webhook = generatTagDeployWebhook($tag->name); + $this->applications = $tag->applications()->get(); + $this->services = $tag->services()->get(); + $this->tag = $tag; + $this->get_deployments(); + } public function get_deployments() { try { - $resource_ids = $this->resources->pluck('id'); + $resource_ids = $this->applications->pluck('id'); $this->deployments_per_tag_per_server = ApplicationDeploymentQueue::whereIn("status", ["in_progress", "queued"])->whereIn('application_id', $resource_ids)->get([ "id", "application_id", @@ -35,7 +50,11 @@ class Show extends Component public function redeploy_all() { try { - $this->resources->each(function ($resource) { + $this->applications->each(function ($resource) { + $deploy = new Deploy(); + $deploy->deploy_resource($resource); + }); + $this->services->each(function ($resource) { $deploy = new Deploy(); $deploy->deploy_resource($resource); }); @@ -44,17 +63,7 @@ class Show extends Component return handleError($e, $this); } } - public function mount() - { - $tag = Tag::ownedByCurrentTeam()->where('name', request()->tag_name)->first(); - if (!$tag) { - return redirect()->route('tags.index'); - } - $this->webhook = generatTagDeployWebhook($tag->name); - $this->resources = $tag->resources()->get(); - $this->tag = $tag; - $this->get_deployments(); - } + public function render() { return view('livewire.tags.show'); diff --git a/app/Models/Application.php b/app/Models/Application.php index b91acdcff..cf3141ed7 100644 --- a/app/Models/Application.php +++ b/app/Models/Application.php @@ -216,6 +216,9 @@ class Application extends BaseModel { return $this->morphToMany(Tag::class, 'taggable'); } + public function project() { + return data_get($this, 'environment.project'); + } public function team() { return data_get($this, 'environment.project.team'); diff --git a/app/Models/Service.php b/app/Models/Service.php index b6d5e86d3..244964db1 100644 --- a/app/Models/Service.php +++ b/app/Models/Service.php @@ -16,6 +16,10 @@ class Service extends BaseModel { return 'service'; } + public function project() + { + return data_get($this, 'environment.project'); + } public function team() { return data_get($this, 'environment.project.team'); diff --git a/app/Models/Tag.php b/app/Models/Tag.php index 02b3a7ff5..b7d50b84f 100644 --- a/app/Models/Tag.php +++ b/app/Models/Tag.php @@ -24,9 +24,8 @@ class Tag extends BaseModel { return $this->morphedByMany(Application::class, 'taggable'); } - - public function resources() { - return $this->applications(); + public function services() + { + return $this->morphedByMany(Service::class, 'taggable'); } - } diff --git a/bootstrap/helpers/applications.php b/bootstrap/helpers/applications.php index de381212f..5e0040872 100644 --- a/bootstrap/helpers/applications.php +++ b/bootstrap/helpers/applications.php @@ -1,5 +1,6 @@ update([ + 'status' => ApplicationDeploymentStatus::IN_PROGRESS->value, + ]); dispatch(new ApplicationDeploymentJob( application_deployment_queue_id: $deployment->id, )); @@ -40,6 +44,9 @@ function queue_next_deployment(Application $application) $server_id = $application->destination->server_id; $next_found = ApplicationDeploymentQueue::where('server_id', $server_id)->where('status', 'queued')->get()->sortBy('created_at')->first(); if ($next_found) { + $next_found->update([ + 'status' => ApplicationDeploymentStatus::IN_PROGRESS->value, + ]); dispatch(new ApplicationDeploymentJob( application_deployment_queue_id: $next_found->id, )); diff --git a/config/sentry.php b/config/sentry.php index 699995883..ba9cad2a6 100644 --- a/config/sentry.php +++ b/config/sentry.php @@ -7,7 +7,7 @@ return [ // The release version of your application // Example with dynamic git hash: trim(exec('git --git-dir ' . base_path('.git') . ' log --pretty="%h" -n1 HEAD')) - 'release' => '4.0.0-beta.205', + 'release' => '4.0.0-beta.206', // When left empty or `null` the Laravel environment will be used 'environment' => config('app.env'), diff --git a/config/version.php b/config/version.php index ff50755a2..b5ee31af0 100644 --- a/config/version.php +++ b/config/version.php @@ -1,3 +1,3 @@ false, 'disabled' => false, 'action' => 'delete', + 'content' => null, ])
- @if ($disabled) - {{ $buttonTitle }} - @elseif ($isErrorButton) - {{ $buttonTitle }} + @if ($content) +
+ {{ $content }} +
@else - {{ $buttonTitle }} + @if ($disabled) + {{ $buttonTitle }} + @elseif ($isErrorButton) + {{ $buttonTitle }} + @else + {{ $buttonTitle }} + @endif @endif