diff --git a/CONTRIBUTION.md b/CONTRIBUTION.md index c139793ec..02a21573c 100644 --- a/CONTRIBUTION.md +++ b/CONTRIBUTION.md @@ -30,5 +30,5 @@ Your horizon (Laravel scheduler): `localhost:8000/horizon` - Only reachable if y Mails are caught by Mailpit: `localhost:8025` ## New Service Contribution -Check out the docs [here](https://coolify.io/docs/resources/services/add-service). +Check out the docs [here](https://coolify.io/docs/knowledge-base/add-a-service). diff --git a/app/Jobs/ApplicationDeploymentJob.php b/app/Jobs/ApplicationDeploymentJob.php index 3d04be7d3..1717c5d08 100644 --- a/app/Jobs/ApplicationDeploymentJob.php +++ b/app/Jobs/ApplicationDeploymentJob.php @@ -710,7 +710,7 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted private function save_environment_variables() { $envs = collect([]); - $ports = $this->application->settings->is_static ? [80] : $this->application->ports_exposes_array; + $ports = $this->application->main_port(); if ($this->pull_request_id !== 0) { $this->env_filename = ".env-pr-$this->pull_request_id"; foreach ($this->application->environment_variables_preview as $env) { @@ -727,14 +727,15 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted $envs->push($env->key . '=' . $real_value); } // Add PORT if not exists, use the first port as default - if ($this->application->environment_variables_preview->filter(fn ($env) => Str::of($env)->startsWith('PORT'))->isEmpty()) { + if ($this->application->environment_variables_preview->where('key', 'PORT')->isEmpty()) { $envs->push("PORT={$ports[0]}"); } // Add HOST if not exists - if ($this->application->environment_variables_preview->filter(fn ($env) => Str::of($env)->startsWith('HOST'))->isEmpty()) { + if ($this->application->environment_variables_preview->where('key', 'HOST')->isEmpty()) { $envs->push("HOST=0.0.0.0"); } - if ($this->application->environment_variables_preview->filter(fn ($env) => Str::of($env)->startsWith('SOURCE_COMMIT'))->isEmpty()) { + // Add SOURCE_COMMIT if not exists + if ($this->application->environment_variables_preview->where('key', 'SOURCE_COMMIT')->isEmpty()) { if (!is_null($this->commit)) { $envs->push("SOURCE_COMMIT={$this->commit}"); } else { @@ -760,14 +761,15 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted $envs->push($env->key . '=' . $real_value); } // Add PORT if not exists, use the first port as default - if ($this->application->environment_variables->filter(fn ($env) => Str::of($env)->startsWith('PORT'))->isEmpty()) { + if ($this->application->environment_variables->where('key', 'PORT')->isEmpty()) { $envs->push("PORT={$ports[0]}"); } // Add HOST if not exists - if ($this->application->environment_variables->filter(fn ($env) => Str::of($env)->startsWith('HOST'))->isEmpty()) { + if ($this->application->environment_variables->where('key', 'HOST')->isEmpty()) { $envs->push("HOST=0.0.0.0"); } - if ($this->application->environment_variables->filter(fn ($env) => Str::of($env)->startsWith('SOURCE_COMMIT'))->isEmpty()) { + // Add SOURCE_COMMIT if not exists + if ($this->application->environment_variables->where('key', 'SOURCE_COMMIT')->isEmpty()) { if (!is_null($this->commit)) { $envs->push("SOURCE_COMMIT={$this->commit}"); } else { @@ -1214,7 +1216,7 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted private function generate_compose_file() { $this->create_workdir(); - $ports = $this->application->settings->is_static ? [80] : $this->application->ports_exposes_array; + $ports = $this->application->main_port(); $onlyPort = null; if (count($ports) > 0) { $onlyPort = $ports[0]; diff --git a/app/Livewire/Project/Edit.php b/app/Livewire/Project/Edit.php index d222917a6..8a35eff7f 100644 --- a/app/Livewire/Project/Edit.php +++ b/app/Livewire/Project/Edit.php @@ -12,28 +12,6 @@ class Edit extends Component 'project.name' => 'required|min:3|max:255', 'project.description' => 'nullable|string|max:255', ]; - protected $listeners = ['refreshEnvs' => '$refresh', 'saveKey' => 'saveKey']; - - public function saveKey($data) - { - try { - $found = $this->project->environment_variables()->where('key', $data['key'])->first(); - if ($found) { - throw new \Exception('Variable already exists.'); - } - $this->project->environment_variables()->create([ - 'key' => $data['key'], - 'value' => $data['value'], - 'is_multiline' => $data['is_multiline'], - 'is_literal' => $data['is_literal'], - 'type' => 'project', - 'team_id' => currentTeam()->id, - ]); - $this->project->refresh(); - } catch (\Throwable $e) { - return handleError($e, $this); - } - } public function mount() { $projectUuid = request()->route('project_uuid'); diff --git a/app/Livewire/Project/EnvironmentEdit.php b/app/Livewire/Project/EnvironmentEdit.php index 173d946f3..cd952a961 100644 --- a/app/Livewire/Project/EnvironmentEdit.php +++ b/app/Livewire/Project/EnvironmentEdit.php @@ -16,29 +16,6 @@ class EnvironmentEdit extends Component 'environment.name' => 'required|min:3|max:255', 'environment.description' => 'nullable|min:3|max:255', ]; - protected $listeners = ['refreshEnvs' => '$refresh', 'saveKey' => 'saveKey']; - - public function saveKey($data) - { - try { - $found = $this->environment->environment_variables()->where('key', $data['key'])->first(); - if ($found) { - throw new \Exception('Variable already exists.'); - } - $this->environment->environment_variables()->create([ - 'key' => $data['key'], - 'value' => $data['value'], - 'is_multiline' => $data['is_multiline'], - 'is_literal' => $data['is_literal'], - 'type' => 'environment', - 'team_id' => currentTeam()->id, - ]); - $this->environment->refresh(); - } catch (\Throwable $e) { - return handleError($e, $this); - } - } - public function mount() { $this->parameters = get_route_parameters(); diff --git a/app/Livewire/SharedVariables/Environment/Index.php b/app/Livewire/SharedVariables/Environment/Index.php new file mode 100644 index 000000000..34f33ef5d --- /dev/null +++ b/app/Livewire/SharedVariables/Environment/Index.php @@ -0,0 +1,19 @@ +projects = Project::ownedByCurrentTeam()->get(); + } + public function render() + { + return view('livewire.shared-variables.environment.index'); + } +} diff --git a/app/Livewire/SharedVariables/Environment/Show.php b/app/Livewire/SharedVariables/Environment/Show.php new file mode 100644 index 000000000..29fd91153 --- /dev/null +++ b/app/Livewire/SharedVariables/Environment/Show.php @@ -0,0 +1,47 @@ + '$refresh', 'saveKey' => 'saveKey']; + + public function saveKey($data) + { + try { + $found = $this->environment->environment_variables()->where('key', $data['key'])->first(); + if ($found) { + throw new \Exception('Variable already exists.'); + } + $this->environment->environment_variables()->create([ + 'key' => $data['key'], + 'value' => $data['value'], + 'is_multiline' => $data['is_multiline'], + 'is_literal' => $data['is_literal'], + 'type' => 'environment', + 'team_id' => currentTeam()->id, + ]); + $this->environment->refresh(); + } catch (\Throwable $e) { + return handleError($e, $this); + } + } + public function mount() + { + $this->parameters = get_route_parameters(); + $this->project = Project::ownedByCurrentTeam()->where('uuid', request()->route('project_uuid'))->first(); + $this->environment = $this->project->environments()->where('name', request()->route('environment_name'))->first(); + } + public function render() + { + return view('livewire.shared-variables.environment.show'); + } +} diff --git a/app/Livewire/SharedVariables/Index.php b/app/Livewire/SharedVariables/Index.php new file mode 100644 index 000000000..61c31e9f8 --- /dev/null +++ b/app/Livewire/SharedVariables/Index.php @@ -0,0 +1,13 @@ +projects = Project::ownedByCurrentTeam()->get(); + } + public function render() + { + return view('livewire.shared-variables.project.index'); + } +} diff --git a/app/Livewire/SharedVariables/Project/Show.php b/app/Livewire/SharedVariables/Project/Show.php new file mode 100644 index 000000000..a172c52f0 --- /dev/null +++ b/app/Livewire/SharedVariables/Project/Show.php @@ -0,0 +1,47 @@ + '$refresh', 'saveKey' => 'saveKey']; + + public function saveKey($data) + { + try { + $found = $this->project->environment_variables()->where('key', $data['key'])->first(); + if ($found) { + throw new \Exception('Variable already exists.'); + } + $this->project->environment_variables()->create([ + 'key' => $data['key'], + 'value' => $data['value'], + 'is_multiline' => $data['is_multiline'], + 'is_literal' => $data['is_literal'], + 'type' => 'project', + 'team_id' => currentTeam()->id, + ]); + $this->project->refresh(); + } catch (\Throwable $e) { + return handleError($e, $this); + } + } + public function mount() + { + $projectUuid = request()->route('project_uuid'); + $teamId = currentTeam()->id; + $project = Project::where('team_id', $teamId)->where('uuid', $projectUuid)->first(); + if (!$project) { + return redirect()->route('dashboard'); + } + $this->project = $project; + } + public function render() + { + return view('livewire.shared-variables.project.show'); + } +} diff --git a/app/Livewire/TeamSharedVariablesIndex.php b/app/Livewire/SharedVariables/Team/Index.php similarity index 88% rename from app/Livewire/TeamSharedVariablesIndex.php rename to app/Livewire/SharedVariables/Team/Index.php index eeee30ab9..ef5c7472c 100644 --- a/app/Livewire/TeamSharedVariablesIndex.php +++ b/app/Livewire/SharedVariables/Team/Index.php @@ -1,11 +1,11 @@ '$refresh', 'saveKey' => 'saveKey']; @@ -37,6 +37,6 @@ class TeamSharedVariablesIndex extends Component } public function render() { - return view('livewire.team-shared-variables-index'); + return view('livewire.shared-variables.team.index'); } } diff --git a/app/Livewire/Team/Storage/Create.php b/app/Livewire/Storage/Create.php similarity index 95% rename from app/Livewire/Team/Storage/Create.php rename to app/Livewire/Storage/Create.php index a25fc9821..d1af807d5 100644 --- a/app/Livewire/Team/Storage/Create.php +++ b/app/Livewire/Storage/Create.php @@ -1,6 +1,6 @@ storage->team_id = currentTeam()->id; $this->storage->testConnection(); $this->storage->save(); - return redirect()->route('team.storage.show', $this->storage->uuid); + return redirect()->route('storage.show', $this->storage->uuid); } catch (\Throwable $e) { $this->dispatch('error', 'Failed to create storage.', $e->getMessage()); // return handleError($e, $this); diff --git a/app/Livewire/Team/Storage/Form.php b/app/Livewire/Storage/Form.php similarity index 94% rename from app/Livewire/Team/Storage/Form.php rename to app/Livewire/Storage/Form.php index 1fd0d470b..79c1f0c30 100644 --- a/app/Livewire/Team/Storage/Form.php +++ b/app/Livewire/Storage/Form.php @@ -1,6 +1,6 @@ storage->delete(); - return redirect()->route('team.storage.index'); + return redirect()->route('storage.index'); } catch (\Throwable $e) { return handleError($e, $this); } diff --git a/app/Livewire/Team/Storage/Index.php b/app/Livewire/Storage/Index.php similarity index 73% rename from app/Livewire/Team/Storage/Index.php rename to app/Livewire/Storage/Index.php index c15834564..f071a0af0 100644 --- a/app/Livewire/Team/Storage/Index.php +++ b/app/Livewire/Storage/Index.php @@ -1,6 +1,6 @@ storage = S3Storage::ownedByCurrentTeam()->whereUuid(request()->storage_uuid)->first(); + if (!$this->storage) { + abort(404); + } + } + public function render() + { + return view('livewire.storage.show'); + } +} diff --git a/app/Livewire/Team/Storage/Show.php b/app/Livewire/Team/Storage/Show.php index 6fbb6034f..ab2acbbb9 100644 --- a/app/Livewire/Team/Storage/Show.php +++ b/app/Livewire/Team/Storage/Show.php @@ -17,6 +17,6 @@ class Show extends Component } public function render() { - return view('livewire.team.storage.show'); + return view('livewire.storage.show'); } } diff --git a/app/Models/Application.php b/app/Models/Application.php index 971f1e894..f28d389f4 100644 --- a/app/Models/Application.php +++ b/app/Models/Application.php @@ -346,6 +346,10 @@ class Application extends BaseModel } return null; } + public function main_port() + { + return $this->settings->is_static ? [80] : $this->ports_exposes_array; + } public function environment_variables(): HasMany { return $this->hasMany(EnvironmentVariable::class)->where('is_preview', false)->orderBy('key', 'asc'); diff --git a/app/Models/S3Storage.php b/app/Models/S3Storage.php index 9d60ce491..dc0b93466 100644 --- a/app/Models/S3Storage.php +++ b/app/Models/S3Storage.php @@ -48,7 +48,7 @@ class S3Storage extends BaseModel if ($this->unusable_email_sent === false && is_transactional_emails_active()) { $mail = new MailMessage(); $mail->subject('Coolify: S3 Storage Connection Error'); - $mail->view('emails.s3-connection-error', ['name' => $this->name, 'reason' => $e->getMessage(), 'url' => route('team.storage.show', ['storage_uuid' => $this->uuid])]); + $mail->view('emails.s3-connection-error', ['name' => $this->name, 'reason' => $e->getMessage(), 'url' => route('storage.show', ['storage_uuid' => $this->uuid])]); $users = collect([]); $members = $this->team->members()->get(); foreach ($members as $user) { diff --git a/app/View/Components/Forms/Textarea.php b/app/View/Components/Forms/Textarea.php index 86547cf65..28f4a45ba 100644 --- a/app/View/Components/Forms/Textarea.php +++ b/app/View/Components/Forms/Textarea.php @@ -23,10 +23,11 @@ class Textarea extends Component public bool $disabled = false, public bool $readonly = false, public bool $allowTab = false, + public bool $spellcheck = false, public ?string $helper = null, public bool $realtimeValidation = false, public bool $allowToPeak = true, - public string $defaultClass = "input scrollbar", + public string $defaultClass = "input scrollbar font-mono", public string $defaultClassInput = "input" ) { // diff --git a/bootstrap/helpers/services.php b/bootstrap/helpers/services.php index 8e3c0337e..5b71a8b10 100644 --- a/bootstrap/helpers/services.php +++ b/bootstrap/helpers/services.php @@ -18,7 +18,7 @@ function collectRegex(string $name) } function replaceVariables($variable) { - return $variable->replaceFirst('$', '')->replaceFirst('{', '')->replaceLast('}', ''); + return $variable->after('${')->before('}'); } function getFilesystemVolumesFromServer(ServiceApplication|ServiceDatabase|Application $oneService, bool $isInit = false) diff --git a/config/sentry.php b/config/sentry.php index 416daa809..bfdaf0b4c 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.267', + 'release' => '4.0.0-beta.268', // 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 66b6ee419..b65f24d33 100644 --- a/config/version.php +++ b/config/version.php @@ -1,3 +1,3 @@ \ No newline at end of file diff --git a/resources/views/components/forms/textarea.blade.php b/resources/views/components/forms/textarea.blade.php index f5bdc3e7d..2c32c585e 100644 --- a/resources/views/components/forms/textarea.blade.php +++ b/resources/views/components/forms/textarea.blade.php @@ -56,7 +56,7 @@ @else -