refactor [gitlab]: create merge requests with REST API

GitOrigin-RevId: 2d7e5cc52b597df7790e13489aa00c3e32e6ffae
This commit is contained in:
Ivan Semenov
2026-02-13 14:11:17 +00:00
committed by intellij-monorepo-bot
parent d2a7820f41
commit d94f9eac86
6 changed files with 47 additions and 63 deletions
@@ -1,14 +0,0 @@
mutation ($projectId: ID!, $sourceBranch: String!, $targetBranch: String!, $title: String!, $description: String){
mergeRequestCreate(input: {
projectPath: $projectId,
sourceBranch:$sourceBranch,
targetBranch: $targetBranch,
title: $title,
description: $description
}) {
mergeRequest {
...mergeRequest
}
errors
}
}
@@ -39,8 +39,6 @@ enum class GitLabGQLQuery(val filePath: String) {
@SinceGitLab("13.10")
MERGE_REQUEST_ACCEPT("graphql/query/mergeRequestAccept.graphql"),
@SinceGitLab("13.1")
MERGE_REQUEST_CREATE("graphql/query/mergeRequestCreate.graphql"),
@SinceGitLab("13.12")
MERGE_REQUEST_SET_DRAFT("graphql/query/mergeRequestSetDraft.graphql"),
@SinceGitLab("15.3")
@@ -188,36 +188,8 @@ private data class GitLabUserNamespacesResult(
data class CurrentUser(val namespace: GitLabNamespaceDTO)
}
@SinceGitLab("13.1")
suspend fun GitLabApi.GraphQL.createMergeRequest(
project: GitLabProjectCoordinates,
sourceBranch: String,
targetBranch: String,
title: String,
description: String?,
): HttpResponse<out GitLabGraphQLMutationResultDTO<GitLabMergeRequestDTO>?> {
val parameters = mapOf(
"projectId" to project.projectPath.fullPath(),
"sourceBranch" to sourceBranch,
"targetBranch" to targetBranch,
"title" to title,
"description" to description
)
val request = gitLabQuery(GitLabGQLQuery.MERGE_REQUEST_CREATE, parameters)
return withErrorStats(GitLabGQLQuery.MERGE_REQUEST_CREATE) {
loadResponse<GitLabCreateMergeRequestResult>(request, "mergeRequestCreate")
}
}
private class LabelConnection(pageInfo: GraphQLCursorPageInfoDTO, nodes: List<GitLabLabelDTO>)
: GraphQLConnectionDTO<GitLabLabelDTO>(pageInfo, nodes)
private class WorkItemConnection(pageInfo: GraphQLCursorPageInfoDTO, nodes: List<GitLabWorkItemDTO>)
: GraphQLConnectionDTO<GitLabWorkItemDTO>(pageInfo, nodes)
private class GitLabCreateMergeRequestResult(
mergeRequest: GitLabMergeRequestDTO,
errors: List<String>?,
override val value: GitLabMergeRequestDTO = mergeRequest,
) : GitLabGraphQLMutationResultDTO<GitLabMergeRequestDTO>(errors)
: GraphQLConnectionDTO<GitLabWorkItemDTO>(pageInfo, nodes)
@@ -25,6 +25,7 @@ import org.jetbrains.plugins.gitlab.mergerequest.api.dto.GitLabMergeRequestByBra
import org.jetbrains.plugins.gitlab.mergerequest.api.dto.GitLabMergeRequestDTO
import org.jetbrains.plugins.gitlab.mergerequest.api.dto.GitLabMergeRequestMetricsDTO
import org.jetbrains.plugins.gitlab.mergerequest.api.dto.GitLabMergeRequestRebaseDTO
import org.jetbrains.plugins.gitlab.mergerequest.api.dto.GitLabMergeRequestShortRestDTO
import org.jetbrains.plugins.gitlab.mergerequest.data.GitLabMergeRequestState
import org.jetbrains.plugins.gitlab.mergerequest.data.asApiParameter
import org.jetbrains.plugins.gitlab.util.GitLabApiRequestName
@@ -32,6 +33,28 @@ import java.net.URI
import java.net.http.HttpRequest
import java.net.http.HttpResponse
@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
): HttpResponse<out GitLabMergeRequestShortRestDTO> {
val uri = project.restApiUri
.resolveRelative("merge_requests")
.withQuery {
"source_branch" eq sourceBranch
"target_branch" eq targetBranch
"title" eq title
"description" eq description
}
val request = request(uri).POST(HttpRequest.BodyPublishers.noBody()).build()
return withErrorStats(GitLabApiRequestName.REST_CREATE_MERGE_REQUEST) {
loadJsonValue(request)
}
}
@SinceGitLab("7.0", note = "?search available since 10.4, ?scope since 9.5")
fun getMergeRequestListURI(project: GitLabProjectCoordinates,
searchQuery: String): URI =
@@ -41,11 +41,11 @@ import org.jetbrains.plugins.gitlab.api.dto.GitLabWorkItemDTO.WorkItemType
import org.jetbrains.plugins.gitlab.api.getResultOrThrow
import org.jetbrains.plugins.gitlab.api.request.createAllProjectLabelsFlow
import org.jetbrains.plugins.gitlab.api.request.createAllWorkItemsFlow
import org.jetbrains.plugins.gitlab.api.request.createMergeRequest
import org.jetbrains.plugins.gitlab.api.request.getProjectNamespace
import org.jetbrains.plugins.gitlab.api.request.getProjectUsers
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
@@ -84,7 +84,12 @@ interface GitLabProject {
* 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.
*/
suspend fun createMergeRequestAndAwaitCompletion(sourceBranch: String, targetBranch: String, title: String, description: String?): GitLabMergeRequestDTO
suspend fun createMergeRequestAndAwaitCompletion(
sourceBranch: String,
targetBranch: String,
title: String,
description: String?,
): GitLabMergeRequestDTO
suspend fun adjustReviewers(mrIid: String, reviewers: List<GitLabUserDTO>): GitLabMergeRequestDTO
fun reloadData()
@@ -155,22 +160,23 @@ class GitLabLazyProject(
}
@Throws(GitLabGraphQLMutationException::class)
override suspend fun createMergeRequestAndAwaitCompletion(sourceBranch: String, targetBranch: String, title: String, description: String?): GitLabMergeRequestDTO {
override suspend fun createMergeRequestAndAwaitCompletion(
sourceBranch: String,
targetBranch: String,
title: String,
description: String?,
): GitLabMergeRequestDTO {
return cs.async(Dispatchers.IO) {
var data: GitLabMergeRequestDTO = api.graphQL.createMergeRequest(projectCoordinates, sourceBranch, targetBranch, title, description).getResultOrThrow()
val iid = data.iid
var attempts = 1
while (attempts++ < GitLabRegistry.getRequestPollingAttempts()) {
val updatedMr = api.graphQL.loadMergeRequest(projectCoordinates, iid).body()
requireNotNull(updatedMr)
data = updatedMr
if (data.diffRefs != null) break
val iid = api.rest.createMergeRequest(projectCoordinates, sourceBranch, targetBranch, title, description).body().iid
val attempts = GitLabRegistry.getRequestPollingAttempts()
repeat(attempts) {
val data = api.graphQL.loadMergeRequest(projectCoordinates, iid).body()
if (data?.diffRefs != null) {
return@async data
}
delay(GitLabRegistry.getRequestPollingIntervalMillis().toLong())
}
data
error("Merge request $iid was created but the data was not loaded within $attempts attempts.")
}.await()
}
@@ -96,7 +96,7 @@ object GitLabStatistics {
//endregion
//region Counters
private val COUNTERS_GROUP = EventLogGroup("vcs.gitlab.counters", version = 29)
private val COUNTERS_GROUP = EventLogGroup("vcs.gitlab.counters", version = 30)
/**
* Server metadata was fetched
@@ -348,6 +348,7 @@ enum class GitLabApiRequestName {
REST_CREATE_DRAFT_NOTE,
REST_UPDATE_DRAFT_NOTE,
REST_GET_MERGE_REQUESTS,
REST_CREATE_MERGE_REQUEST,
REST_APPROVE_MERGE_REQUEST,
REST_UNAPPROVE_MERGE_REQUEST,
REST_REBASE_MERGE_REQUEST,
@@ -384,7 +385,6 @@ enum class GitLabApiRequestName {
GQL_CREATE_SNIPPET,
GQL_UPDATE_SNIPPET_BLOB,
GQL_MERGE_REQUEST_ACCEPT,
GQL_MERGE_REQUEST_CREATE,
GQL_MERGE_REQUEST_SET_DRAFT,
GQL_MERGE_REQUEST_SET_REVIEWERS,
GQL_MERGE_REQUEST_UPDATE,
@@ -409,7 +409,6 @@ enum class GitLabApiRequestName {
GitLabGQLQuery.CREATE_SNIPPET -> GQL_CREATE_SNIPPET
GitLabGQLQuery.UPDATE_SNIPPET_BLOB -> GQL_UPDATE_SNIPPET_BLOB
GitLabGQLQuery.MERGE_REQUEST_ACCEPT -> GQL_MERGE_REQUEST_ACCEPT
GitLabGQLQuery.MERGE_REQUEST_CREATE -> GQL_MERGE_REQUEST_CREATE
GitLabGQLQuery.MERGE_REQUEST_SET_DRAFT -> GQL_MERGE_REQUEST_SET_DRAFT
GitLabGQLQuery.MERGE_REQUEST_SET_REVIEWERS -> GQL_MERGE_REQUEST_SET_REVIEWERS
GitLabGQLQuery.MERGE_REQUEST_UPDATE -> GQL_MERGE_REQUEST_UPDATE