162 lines
6.0 KiB
PHP
162 lines
6.0 KiB
PHP
<?php
|
|
|
|
namespace App\Actions\Git;
|
|
|
|
use App\Actions\Git\Data\GitPullRequest;
|
|
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 ResolveTicketPullRequestMatches
|
|
{
|
|
public function __construct(
|
|
private readonly GitProviderManager $gitProviderManager,
|
|
private readonly TicketKeyReferenceMatcher $ticketKeyReferenceMatcher,
|
|
) {}
|
|
|
|
/**
|
|
* @return array<int, array{
|
|
* error: string|null,
|
|
* pull_requests: array<int, array{
|
|
* html_url: string,
|
|
* number: string,
|
|
* source_branch: string,
|
|
* status: string,
|
|
* title: string
|
|
* }>,
|
|
* 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 [
|
|
'error' => null,
|
|
'pull_requests' => [],
|
|
'repository_connection' => $this->repositoryConnectionPayload(
|
|
$repositoryConnection,
|
|
false,
|
|
),
|
|
];
|
|
}
|
|
|
|
try {
|
|
$pullRequests = collect(
|
|
$this->gitProviderManager
|
|
->client($userGitConnection->provider)
|
|
->listPullRequests(
|
|
$userGitConnection->base_url,
|
|
$userGitConnection->api_token,
|
|
$repositoryConnection->owner_name,
|
|
$repositoryConnection->repository_name,
|
|
),
|
|
)
|
|
->filter(fn (GitPullRequest $pullRequest): bool => $this->ticketKeyReferenceMatcher->matches(
|
|
$ticket->ticket_key,
|
|
$pullRequest->sourceBranch,
|
|
))
|
|
->map(fn (GitPullRequest $pullRequest): array => [
|
|
'html_url' => $pullRequest->htmlUrl,
|
|
'number' => $pullRequest->number,
|
|
'source_branch' => $pullRequest->sourceBranch,
|
|
'status' => $pullRequest->status,
|
|
'title' => $pullRequest->title,
|
|
])
|
|
->values()
|
|
->all();
|
|
|
|
$error = null;
|
|
} catch (Throwable) {
|
|
$error = 'KanbanGit could not load pull requests from this repository right now.';
|
|
$pullRequests = [];
|
|
}
|
|
|
|
return [
|
|
'error' => $error,
|
|
'pull_requests' => $pullRequests,
|
|
'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();
|
|
}
|
|
}
|