Files
KanbanGit/app/Actions/Git/ResolveTicketBranchMatches.php
T

152 lines
5.5 KiB
PHP

<?php
namespace App\Actions\Git;
use App\Actions\Git\Data\GitBranch;
use App\Models\Project;
use App\Models\RepositoryConnection;
use App\Models\Ticket;
use App\Models\User;
use App\Models\UserGitConnection;
use Illuminate\Support\Collection;
use Throwable;
class ResolveTicketBranchMatches
{
public function __construct(
private readonly GitProviderManager $gitProviderManager,
private readonly TicketKeyReferenceMatcher $ticketKeyReferenceMatcher,
) {}
/**
* @return array<int, array{
* branches: array<int, array{name: string}>,
* error: string|null,
* repository_connection: array{
* base_url: string,
* created_at: string|null,
* has_personal_access: bool,
* id: int,
* owner_name: string,
* project_id: int,
* provider: string,
* provider_label: string,
* provider_repository_id: string,
* repository_full_name: string,
* repository_name: string,
* repository_url: string,
* updated_at: string|null
* }
* }>
*/
public function handle(User $user, Project $project, Ticket $ticket): array
{
/** @var Collection<int, RepositoryConnection> $repositoryConnections */
$repositoryConnections = $project->repositoryConnections()
->get();
return $repositoryConnections
->map(function (RepositoryConnection $repositoryConnection) use ($ticket, $user): array {
$userGitConnection = $this->matchingUserGitConnection($user, $repositoryConnection);
$hasPersonalAccess = $userGitConnection !== null;
if ($userGitConnection === null) {
return [
'branches' => [],
'error' => null,
'repository_connection' => $this->repositoryConnectionPayload(
$repositoryConnection,
false,
),
];
}
try {
$branches = collect(
$this->gitProviderManager
->client($userGitConnection->provider)
->listBranches(
$userGitConnection->base_url,
$userGitConnection->api_token,
$repositoryConnection->owner_name,
$repositoryConnection->repository_name,
),
)
->filter(fn (GitBranch $branch): bool => $this->ticketKeyReferenceMatcher->matches(
$ticket->ticket_key,
$branch->name,
))
->map(fn (GitBranch $branch): array => [
'name' => $branch->name,
])
->values()
->all();
$error = null;
} catch (Throwable) {
$branches = [];
$error = 'KanbanGit could not load branches from this repository right now.';
}
return [
'branches' => $branches,
'error' => $error,
'repository_connection' => $this->repositoryConnectionPayload(
$repositoryConnection,
$hasPersonalAccess,
),
];
})
->values()
->all();
}
/**
* @return array{
* base_url: string,
* created_at: string|null,
* has_personal_access: bool,
* id: int,
* owner_name: string,
* project_id: int,
* provider: string,
* provider_label: string,
* provider_repository_id: string,
* repository_full_name: string,
* repository_name: string,
* repository_url: string,
* updated_at: string|null
* }
*/
private function repositoryConnectionPayload(
RepositoryConnection $repositoryConnection,
bool $hasPersonalAccess,
): array {
return [
'base_url' => $repositoryConnection->base_url,
'created_at' => $repositoryConnection->created_at?->toISOString(),
'has_personal_access' => $hasPersonalAccess,
'id' => $repositoryConnection->id,
'owner_name' => $repositoryConnection->owner_name,
'project_id' => $repositoryConnection->project_id,
'provider' => $repositoryConnection->provider->value,
'provider_label' => $repositoryConnection->provider->label(),
'provider_repository_id' => $repositoryConnection->provider_repository_id,
'repository_full_name' => $repositoryConnection->repository_full_name,
'repository_name' => $repositoryConnection->repository_name,
'repository_url' => $repositoryConnection->repository_url,
'updated_at' => $repositoryConnection->updated_at?->toISOString(),
];
}
private function matchingUserGitConnection(
User $user,
RepositoryConnection $repositoryConnection,
): ?UserGitConnection {
return $user->gitConnections()
->where('provider', $repositoryConnection->provider)
->where('base_url', $repositoryConnection->base_url)
->first();
}
}