105 lines
3.7 KiB
PHP
105 lines
3.7 KiB
PHP
<?php
|
|
|
|
namespace App\Actions\Tickets;
|
|
|
|
use App\Actions\Git\GitProviderManager;
|
|
use App\Actions\Git\ValidateGitBranchName;
|
|
use App\Models\Project;
|
|
use App\Models\RepositoryConnection;
|
|
use App\Models\Ticket;
|
|
use App\Models\User;
|
|
use App\Models\UserGitConnection;
|
|
use Illuminate\Support\Arr;
|
|
use Illuminate\Validation\ValidationException;
|
|
use Throwable;
|
|
|
|
class CreateProjectTicketBranch
|
|
{
|
|
public function __construct(
|
|
private readonly GitProviderManager $gitProviderManager,
|
|
private readonly ValidateGitBranchName $validateGitBranchName,
|
|
private readonly ValidateProjectTicketBranch $validateProjectTicketBranch,
|
|
) {}
|
|
|
|
/**
|
|
* @param array{branch_name: string, repository_connection_id: int} $validated
|
|
* @return array{branch_name: string, repository_full_name: string}
|
|
*/
|
|
public function handle(Project $project, Ticket $ticket, User $user, array $validated): array
|
|
{
|
|
$repositoryConnectionId = (int) Arr::get($validated, 'repository_connection_id');
|
|
$branchName = trim((string) Arr::get($validated, 'branch_name'));
|
|
|
|
$repositoryConnection = $this->projectRepositoryConnection($project, $repositoryConnectionId);
|
|
$userGitConnection = $this->matchingUserGitConnection($user->id, $repositoryConnection);
|
|
|
|
if ($userGitConnection === null) {
|
|
throw ValidationException::withMessages([
|
|
'repository_connection_id' => 'Connect a matching Git connection in your user settings first.',
|
|
]);
|
|
}
|
|
|
|
$syntaxMessage = $this->validateGitBranchName->message($branchName);
|
|
|
|
if ($syntaxMessage !== null) {
|
|
throw ValidationException::withMessages([
|
|
'branch_name' => $syntaxMessage,
|
|
]);
|
|
}
|
|
|
|
$validation = $this->validateProjectTicketBranch->handle($project, $ticket, $user, $validated);
|
|
|
|
if (! $validation['is_valid']) {
|
|
throw ValidationException::withMessages([
|
|
'branch_name' => $validation['message'],
|
|
]);
|
|
}
|
|
|
|
$gitProvider = $this->gitProviderManager->client($userGitConnection->provider);
|
|
|
|
try {
|
|
$repository = $gitProvider->getRepository(
|
|
$userGitConnection->base_url,
|
|
$userGitConnection->api_token,
|
|
$repositoryConnection->owner_name,
|
|
$repositoryConnection->repository_name,
|
|
);
|
|
|
|
$gitProvider->createBranch(
|
|
$userGitConnection->base_url,
|
|
$userGitConnection->api_token,
|
|
$repositoryConnection->owner_name,
|
|
$repositoryConnection->repository_name,
|
|
$branchName,
|
|
$repository->defaultBranch,
|
|
);
|
|
} catch (Throwable) {
|
|
throw ValidationException::withMessages([
|
|
'branch_name' => sprintf('%s could not create this branch right now.', config('app.name')),
|
|
]);
|
|
}
|
|
|
|
return [
|
|
'branch_name' => $branchName,
|
|
'repository_full_name' => $repositoryConnection->repository_full_name,
|
|
];
|
|
}
|
|
|
|
private function projectRepositoryConnection(Project $project, int $repositoryConnectionId): RepositoryConnection
|
|
{
|
|
return $project->repositoryConnections()
|
|
->findOrFail($repositoryConnectionId);
|
|
}
|
|
|
|
private function matchingUserGitConnection(
|
|
int $userId,
|
|
RepositoryConnection $repositoryConnection,
|
|
): ?UserGitConnection {
|
|
return UserGitConnection::query()
|
|
->where('user_id', $userId)
|
|
->where('provider', $repositoryConnection->provider)
|
|
->where('base_url', $repositoryConnection->base_url)
|
|
->first();
|
|
}
|
|
}
|