diff --git a/app/Actions/SourceControl/ConnectSourceControl.php b/app/Actions/SourceControl/ConnectSourceControl.php index 3fe72d7a..4c2fae46 100644 --- a/app/Actions/SourceControl/ConnectSourceControl.php +++ b/app/Actions/SourceControl/ConnectSourceControl.php @@ -3,6 +3,7 @@ namespace App\Actions\SourceControl; use App\Models\SourceControl; +use Illuminate\Support\Arr; use Illuminate\Support\Facades\Validator; use Illuminate\Validation\Rule; use Illuminate\Validation\ValidationException; @@ -16,6 +17,7 @@ public function connect(array $input): void 'provider' => $input['provider'], 'profile' => $input['name'], 'access_token' => $input['token'], + 'url' => Arr::has($input, 'url') ? $input['url'] : null, ]); if (! $sourceControl->provider()->connect()) { @@ -44,6 +46,11 @@ private function validate(array $input): void 'token' => [ 'required', ], + 'url' => [ + 'nullable', + 'url:http,https', + 'ends_with:/', + ], ]; Validator::make($input, $rules)->validate(); } diff --git a/app/SourceControlProviders/Gitlab.php b/app/SourceControlProviders/Gitlab.php index 0933f452..6b546f16 100755 --- a/app/SourceControlProviders/Gitlab.php +++ b/app/SourceControlProviders/Gitlab.php @@ -10,12 +10,14 @@ class Gitlab extends AbstractSourceControlProvider { - protected string $apiUrl = 'https://gitlab.com/api/v4'; + protected string $defaultApiHost = 'https://gitlab.com/'; + + protected string $apiVersion = 'api/v4'; public function connect(): bool { $res = Http::withToken($this->sourceControl->access_token) - ->get($this->apiUrl.'/projects'); + ->get($this->getApiUrl().'/projects'); return $res->successful(); } @@ -27,7 +29,7 @@ public function getRepo(string $repo = null): mixed { $repository = $repo ? urlencode($repo) : null; $res = Http::withToken($this->sourceControl->access_token) - ->get($this->apiUrl.'/projects/'.$repository.'/repository/commits'); + ->get($this->getApiUrl().'/projects/'.$repository.'/repository/commits'); $this->handleResponseErrors($res, $repo); @@ -36,7 +38,9 @@ public function getRepo(string $repo = null): mixed public function fullRepoUrl(string $repo, string $key): string { - return sprintf('git@gitlab.com-%s:%s.git', $key, $repo); + $host = parse_url($this->getApiUrl())['host']; + + return sprintf('git@%s-%s:%s.git', $host, $key, $repo); } /** @@ -46,7 +50,7 @@ public function deployHook(string $repo, array $events, string $secret): array { $repository = urlencode($repo); $response = Http::withToken($this->sourceControl->access_token)->post( - $this->apiUrl.'/projects/'.$repository.'/hooks', + $this->getApiUrl().'/projects/'.$repository.'/hooks', [ 'description' => 'deploy', 'url' => url('/git-hooks?secret='.$secret), @@ -81,7 +85,7 @@ public function destroyHook(string $repo, string $hookId): void { $repository = urlencode($repo); $response = Http::withToken($this->sourceControl->access_token)->delete( - $this->apiUrl.'/projects/'.$repository.'/hooks/'.$hookId + $this->getApiUrl().'/projects/'.$repository.'/hooks/'.$hookId ); if ($response->status() != 204) { @@ -96,7 +100,7 @@ public function getLastCommit(string $repo, string $branch): ?array { $repository = urlencode($repo); $res = Http::withToken($this->sourceControl->access_token) - ->get($this->apiUrl.'/projects/'.$repository.'/repository/commits?ref_name='.$branch); + ->get($this->getApiUrl().'/projects/'.$repository.'/repository/commits?ref_name='.$branch); $this->handleResponseErrors($res, $repo); @@ -123,7 +127,7 @@ public function deployKey(string $title, string $repo, string $key): void { $repository = urlencode($repo); $response = Http::withToken($this->sourceControl->access_token)->post( - $this->apiUrl.'/projects/'.$repository.'/deploy_keys', + $this->getApiUrl().'/projects/'.$repository.'/deploy_keys', [ 'title' => $title, 'key' => $key, @@ -135,4 +139,13 @@ public function deployKey(string $title, string $repo, string $key): void throw new FailedToDeployGitKey(json_decode($response->body())->message); } } + + public function getApiUrl(): string + { + $host = $this->sourceControl->url === null + ? $this->defaultApiHost + : $this->sourceControl->url; + + return $host.$this->apiVersion; + } } diff --git a/database/factories/SourceControlFactory.php b/database/factories/SourceControlFactory.php index e0d3fb22..7de1a1bb 100644 --- a/database/factories/SourceControlFactory.php +++ b/database/factories/SourceControlFactory.php @@ -17,4 +17,40 @@ public function definition(): array 'access_token' => Str::random(10), ]; } + + public function gitlab(): Factory + { + return $this->state(function (array $attributes) { + return [ + 'provider' => \App\Enums\SourceControl::GITLAB, + ]; + }); + } + + public function github(): Factory + { + return $this->state(function (array $attributes) { + return [ + 'provider' => \App\Enums\SourceControl::GITHUB, + ]; + }); + } + + public function bitbucket(): Factory + { + return $this->state(function (array $attributes) { + return [ + 'provider' => \App\Enums\SourceControl::BITBUCKET, + ]; + }); + } + + public function custom(): Factory + { + return $this->state(function (array $attributes) { + return [ + 'provider' => \App\Enums\SourceControl::CUSTOM, + ]; + }); + } } diff --git a/resources/views/components/input-help.blade.php b/resources/views/components/input-help.blade.php new file mode 100644 index 00000000..808655eb --- /dev/null +++ b/resources/views/components/input-help.blade.php @@ -0,0 +1 @@ +
merge(['class' => 'mt-2 text-sm text-gray-500 dark:text-gray-300']) }}>{{ $slot }}
diff --git a/resources/views/livewire/source-controls/connect.blade.php b/resources/views/livewire/source-controls/connect.blade.php index 6725d883..7d0c82ed 100644 --- a/resources/views/livewire/source-controls/connect.blade.php +++ b/resources/views/livewire/source-controls/connect.blade.php @@ -32,6 +32,17 @@ @enderror + @if($provider === App\Enums\SourceControl::GITLAB) +