mirror of
https://github.com/coollabsio/coolify.git
synced 2026-11-04 10:42:23 +00:00
fix(new-resource): accept a base directory without a leading slash
Closes #12428 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
d8c1b926ca
commit
51029aa8b9
12 files changed
+36
-5
No files matched your search
@@ -165,6 +165,7 @@ class GiteaPrivateRepository extends Component
|
||||
{
|
||||
try {
|
||||
$this->authorize('create', Application::class);
|
||||
$this->base_directory = ValidationPatterns::normalizeDirectoryPath($this->base_directory);
|
||||
|
||||
$validator = validator([
|
||||
'selected_repository_path' => $this->selected_repository_path,
|
||||
|
||||
@@ -202,6 +202,7 @@ class GithubPrivateRepository extends Component
|
||||
{
|
||||
try {
|
||||
$this->authorize('create', Application::class);
|
||||
$this->base_directory = ValidationPatterns::normalizeDirectoryPath($this->base_directory);
|
||||
|
||||
// Validate git repository parts and branch
|
||||
$validator = validator([
|
||||
|
||||
@@ -155,6 +155,7 @@ class GithubPrivateRepositoryDeployKey extends Component
|
||||
|
||||
$privateKey = PrivateKey::ownedByCurrentTeam()->findOrFail($this->private_key_id);
|
||||
|
||||
$this->base_directory = ValidationPatterns::normalizeDirectoryPath($this->base_directory);
|
||||
$this->validate();
|
||||
try {
|
||||
$destination_uuid = $this->query['destination'] ?? null;
|
||||
|
||||
@@ -162,6 +162,7 @@ class GitlabPrivateRepository extends Component
|
||||
{
|
||||
try {
|
||||
$this->authorize('create', Application::class);
|
||||
$this->base_directory = ValidationPatterns::normalizeDirectoryPath($this->base_directory);
|
||||
|
||||
$validator = validator([
|
||||
'selected_repository_path' => $this->selected_repository_path,
|
||||
|
||||
@@ -278,6 +278,7 @@ class PublicGitRepository extends Component
|
||||
{
|
||||
try {
|
||||
$this->authorize('create', Application::class);
|
||||
$this->base_directory = ValidationPatterns::normalizeDirectoryPath($this->base_directory);
|
||||
|
||||
$this->validate();
|
||||
|
||||
|
||||
@@ -576,6 +576,17 @@ class ValidationPatterns
|
||||
return ['nullable', 'string', 'max:'.$maxLength, 'regex:'.self::DIRECTORY_PATH_PATTERN];
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize a typed directory path to the form that DIRECTORY_PATH_PATTERN expects:
|
||||
* "apps/web/" becomes "/apps/web", and an empty value becomes "/".
|
||||
*/
|
||||
public static function normalizeDirectoryPath(?string $path): string
|
||||
{
|
||||
$path = trim(trim((string) $path), '/');
|
||||
|
||||
return '/'.$path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get validation rules for Docker build target fields
|
||||
*/
|
||||
|
||||
@@ -135,7 +135,7 @@
|
||||
file="docker_compose_location" fileLabel="Compose file"
|
||||
defaultFile="/docker-compose.yaml" />
|
||||
@else
|
||||
<x-forms.input wire:model="base_directory" label="Base directory"
|
||||
<x-forms.input id="base_directory" label="Base directory" placeholder="/"
|
||||
helper="Repository directory used as the build root." />
|
||||
@endif
|
||||
</div>
|
||||
|
||||
@@ -85,7 +85,7 @@
|
||||
file="docker_compose_location" fileLabel="Compose file"
|
||||
defaultFile="/docker-compose.yaml" />
|
||||
@else
|
||||
<x-forms.input wire:model="base_directory" label="Base directory"
|
||||
<x-forms.input id="base_directory" label="Base directory" placeholder="/"
|
||||
helper="Repository directory used as the build root." />
|
||||
@endif
|
||||
|
||||
|
||||
@@ -162,7 +162,7 @@
|
||||
file="docker_compose_location" fileLabel="Compose file"
|
||||
defaultFile="/docker-compose.yaml" />
|
||||
@else
|
||||
<x-forms.input wire:model="base_directory" label="Base directory"
|
||||
<x-forms.input id="base_directory" label="Base directory" placeholder="/"
|
||||
helper="Repository directory used as the build root." />
|
||||
@endif
|
||||
</div>
|
||||
|
||||
@@ -139,7 +139,7 @@
|
||||
file="docker_compose_location" fileLabel="Compose file"
|
||||
defaultFile="/docker-compose.yaml" />
|
||||
@else
|
||||
<x-forms.input wire:model="base_directory" label="Base directory"
|
||||
<x-forms.input id="base_directory" label="Base directory" placeholder="/"
|
||||
helper="Repository directory used as the build root." />
|
||||
@endif
|
||||
</div>
|
||||
|
||||
@@ -111,7 +111,7 @@
|
||||
file="docker_compose_location" fileLabel="Compose file"
|
||||
defaultFile="/docker-compose.yaml" />
|
||||
@else
|
||||
<x-forms.input wire:model="base_directory" label="Base directory"
|
||||
<x-forms.input id="base_directory" label="Base directory" placeholder="/"
|
||||
helper="Repository directory used as the build root." />
|
||||
@endif
|
||||
</div>
|
||||
|
||||
@@ -128,6 +128,21 @@ test('deploy key application keeps the base directory for every build pack', fun
|
||||
expect(Application::query()->sole()->base_directory)->toBe('/apps/api');
|
||||
})->with(['dockerfile', 'railpack', 'static', 'dockercompose']);
|
||||
|
||||
test('deploy key application accepts a base directory without a leading slash', function (string $typed) {
|
||||
actAsDeployKeyUser($this->admin, $this->team);
|
||||
|
||||
deployKeyComponent()
|
||||
->call('setPrivateKey', $this->privateKey->id)
|
||||
->set('repository_url', 'git@example.com:owner/monorepo.git')
|
||||
->set('branch', 'main')
|
||||
->set('build_pack', 'dockerfile')
|
||||
->set('base_directory', $typed)
|
||||
->call('submit')
|
||||
->assertHasNoErrors();
|
||||
|
||||
expect(Application::query()->sole()->base_directory)->toBe('/apps/api');
|
||||
})->with(['apps/api', 'apps/api/', ' /apps/api/ ']);
|
||||
|
||||
test('deploy key application uses the repository root when the base directory is empty', function () {
|
||||
actAsDeployKeyUser($this->admin, $this->team);
|
||||
|
||||
|
||||
Reference in new issue
Block a user