refactor [gitlab]: create the merge request and set reviewers in a single request

GitOrigin-RevId: e96410ce67579a318037a092f34150a1ffc415b7
This commit is contained in:
Ivan Semenov
2026-02-13 14:11:17 +00:00
committed by intellij-monorepo-bot
parent d94f9eac86
commit 07ba6e8491
3 changed files with 29 additions and 19 deletions
@@ -33,13 +33,21 @@ import java.net.URI
import java.net.http.HttpRequest
import java.net.http.HttpResponse
/**
* Creates a merge request
*
* Note: reviewer_ids parameter has different behavior depending on the user's subscription plan
* [org.jetbrains.plugins.gitlab.api.data.GitLabPlan.FREE] -- sets only one reviewer from the list (the last one)
* OTHER -- sets all reviewers from the list
*/
@SinceGitLab("14.0", note = "No exact version, but definitely exists in minimal")
suspend fun GitLabApi.Rest.createMergeRequest(
project: GitLabProjectCoordinates,
sourceBranch: String,
targetBranch: String,
title: String,
description: String? = null
description: String? = null,
reviewerIds: List<String>? = null
): HttpResponse<out GitLabMergeRequestShortRestDTO> {
val uri = project.restApiUri
.resolveRelative("merge_requests")
@@ -48,6 +56,7 @@ suspend fun GitLabApi.Rest.createMergeRequest(
"target_branch" eq targetBranch
"title" eq title
"description" eq description
"reviewer_ids" eq reviewerIds
}
val request = request(uri).POST(HttpRequest.BodyPublishers.noBody()).build()
return withErrorStats(GitLabApiRequestName.REST_CREATE_MERGE_REQUEST) {
@@ -8,6 +8,7 @@ import com.intellij.openapi.components.serviceAsync
import com.intellij.openapi.diagnostic.logger
import com.intellij.openapi.project.Project
import com.intellij.platform.util.coroutines.childScope
import com.intellij.util.containers.nullize
import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.CoroutineStart
@@ -27,6 +28,7 @@ import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.shareIn
import kotlinx.coroutines.flow.transformWhile
import org.jetbrains.plugins.gitlab.api.GitLabApi
import org.jetbrains.plugins.gitlab.api.GitLabGidData
import org.jetbrains.plugins.gitlab.api.GitLabGraphQLMutationException
import org.jetbrains.plugins.gitlab.api.GitLabId
import org.jetbrains.plugins.gitlab.api.GitLabProjectCoordinates
@@ -47,7 +49,6 @@ import org.jetbrains.plugins.gitlab.api.request.getProjectUsersURI
import org.jetbrains.plugins.gitlab.mergerequest.api.dto.GitLabMergeRequestDTO
import org.jetbrains.plugins.gitlab.mergerequest.api.request.createMergeRequest
import org.jetbrains.plugins.gitlab.mergerequest.api.request.loadMergeRequest
import org.jetbrains.plugins.gitlab.mergerequest.api.request.mergeRequestSetReviewers
import org.jetbrains.plugins.gitlab.upload.markdownUploadFile
import org.jetbrains.plugins.gitlab.util.GitLabProjectMapping
import org.jetbrains.plugins.gitlab.util.GitLabRegistry
@@ -83,14 +84,18 @@ interface GitLabProject {
* once the merge request was successfully initialized on server.
* The reason for this wait is that GitLab might take a few moments to process the merge request
* before returning one that can be displayed in the IDE in a useful way.
*
* @param reviewers List of reviewer user DTOs to assign to the merge request
* Note: this parameter has different behavior depending on [isMultipleReviewersAllowed] -
* either sets only one reviewer from the list (the last one) or sets all reviewers from the list
*/
suspend fun createMergeRequestAndAwaitCompletion(
sourceBranch: String,
targetBranch: String,
title: String,
description: String?,
reviewers: List<GitLabUserDTO> = emptyList()
): GitLabMergeRequestDTO
suspend fun adjustReviewers(mrIid: String, reviewers: List<GitLabUserDTO>): GitLabMergeRequestDTO
fun reloadData()
@@ -165,9 +170,18 @@ class GitLabLazyProject(
targetBranch: String,
title: String,
description: String?,
reviewers: List<GitLabUserDTO>
): GitLabMergeRequestDTO {
return cs.async(Dispatchers.IO) {
val iid = api.rest.createMergeRequest(projectCoordinates, sourceBranch, targetBranch, title, description).body().iid
val reviewerIds = reviewers.nullize()?.map { GitLabGidData(it.id).guessRestId() }
val iid = api.rest.createMergeRequest(
projectCoordinates,
sourceBranch,
targetBranch,
title,
description,
reviewerIds
).body().iid
val attempts = GitLabRegistry.getRequestPollingAttempts()
repeat(attempts) {
val data = api.graphQL.loadMergeRequest(projectCoordinates, iid).body()
@@ -180,19 +194,6 @@ class GitLabLazyProject(
}.await()
}
@Throws(GitLabGraphQLMutationException::class, IllegalStateException::class)
override suspend fun adjustReviewers(mrIid: String, reviewers: List<GitLabUserDTO>): GitLabMergeRequestDTO {
return cs.async(Dispatchers.IO) {
if (GitLabVersion(15, 3) <= api.getMetadata().version) {
api.graphQL.mergeRequestSetReviewers(projectCoordinates, mrIid, reviewers).getResultOrThrow()
}
else {
api.rest.mergeRequestSetReviewers(projectCoordinates, mrIid, reviewers).body()
api.graphQL.loadMergeRequest(projectCoordinates, mrIid).body() ?: error("Merge request could not be loaded")
}
}.await()
}
override fun reloadData() {
labelsLoader.cancel()
membersLoader.cancel()
@@ -275,9 +275,9 @@ internal class GitLabMergeRequestCreateViewModelImpl(
sourceBranch = gitRemoteBranch.nameForRemoteOperations,
targetBranch = baseBranch.nameForRemoteOperations,
title = titleText.value.ifBlank { gitRemoteBranch.nameForRemoteOperations },
description = descriptionText.value.ifBlank { null }
description = descriptionText.value.ifBlank { null },
reviewers = adjustedReviewers.value
)
projectData.adjustReviewers(mergeRequest.iid, adjustedReviewers.value)
openReviewTabAction(mergeRequest.iid)
onReviewCreated()
GitLabStatistics.logMrCreationSucceeded(project)