user(); abort_unless( $this->permissionService->allows($user, Permission::ProjectWrite, $project), 403, ); $validated = $request->validated(); $repositoryConnectionId = 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) { return response()->json([ 'is_valid' => false, 'message' => 'Connect a matching Git connection in your user settings first.', ]); } $syntaxMessage = $this->validateGitBranchName->message($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 === $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 { $user = $request->user(); abort_unless( $this->permissionService->allows($user, Permission::ProjectWrite, $project), 403, ); $validated = $request->validated(); $repositoryConnectionId = 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, ]); } $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 === $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, $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', "{$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(); } }