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,
])