Add ticket branch discovery by ticket key
This commit is contained in:
@@ -0,0 +1,151 @@
|
||||
<?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();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user