projectPermissionService->userHasPermission($request->user(), $project, 'edit'), 403, ); $repositoryConnection = $this->projectRepositoryConnection( $project, $request->repositoryConnectionId(), ); $userGitConnection = $this->matchingUserGitConnection( $request->user()->id, $repositoryConnection, ); if ($userGitConnection === null) { return response()->json([ 'is_valid' => false, 'message' => 'Connect a matching Git connection in your user settings first.', ]); } $syntaxMessage = $this->validateGitBranchName->message($request->branchName()); if ($syntaxMessage !== null) { return response()->json([ 'is_valid' => false, 'message' => $syntaxMessage, ]); } try { $branchAlreadyExists = collect( $this->gitProviderManager ->client($userGitConnection->provider) ->listBranches( $userGitConnection->base_url, $userGitConnection->api_token, $repositoryConnection->owner_name, $repositoryConnection->repository_name, ), ) ->contains( fn (GitBranch $branch): bool => $branch->name === $request->branchName(), ); } catch (Throwable) { return response()->json([ 'is_valid' => false, 'message' => 'KanbanGit could not validate this branch name right now.', ]); } if ($branchAlreadyExists) { return response()->json([ 'is_valid' => false, 'message' => 'This branch name already exists in the selected repository.', ]); } return response()->json([ 'is_valid' => true, 'message' => "Branch name is available for {$ticket->ticket_key}.", ]); } public function store( StoreProjectTicketBranchRequest $request, Project $project, Ticket $ticket, ): RedirectResponse { abort_unless( $this->projectPermissionService->userHasPermission($request->user(), $project, 'edit'), 403, ); $repositoryConnection = $this->projectRepositoryConnection( $project, $request->repositoryConnectionId(), ); $userGitConnection = $this->matchingUserGitConnection( $request->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($request->branchName()); if ($syntaxMessage !== null) { throw ValidationException::withMessages([ 'branch_name' => $syntaxMessage, ]); } $gitProvider = $this->gitProviderManager->client($userGitConnection->provider); try { $branchAlreadyExists = collect( $gitProvider->listBranches( $userGitConnection->base_url, $userGitConnection->api_token, $repositoryConnection->owner_name, $repositoryConnection->repository_name, ), ) ->contains( fn (GitBranch $branch): bool => $branch->name === $request->branchName(), ); } catch (Throwable) { throw ValidationException::withMessages([ 'branch_name' => 'KanbanGit could not validate this branch name right now.', ]); } if ($branchAlreadyExists) { throw ValidationException::withMessages([ 'branch_name' => 'This branch name already exists in the selected repository.', ]); } 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, $request->branchName(), $repository->defaultBranch, ); } catch (Throwable) { throw ValidationException::withMessages([ 'branch_name' => 'KanbanGit could not create this branch right now.', ]); } return to_route('projects.tickets.show', [$project, $ticket]) ->with( 'status', "{$request->branchName()} was created in {$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(); } }