From d94f9eac866ca0d1fe8d7cfa31ccf3984618ee54 Mon Sep 17 00:00:00 2001 From: Ivan Semenov Date: Wed, 4 Feb 2026 12:51:44 +0100 Subject: [PATCH] refactor [gitlab]: create merge requests with REST API GitOrigin-RevId: 2d7e5cc52b597df7790e13489aa00c3e32e6ffae --- .../graphql/query/mergeRequestCreate.graphql | 14 -------- .../plugins/gitlab/api/GitLabGQLQuery.kt | 2 -- .../gitlab/api/request/GitLabProjectApi.kt | 30 +--------------- .../api/request/GitLabMergeRequestsApi.kt | 23 ++++++++++++ .../gitlab/mergerequest/data/GitLabProject.kt | 36 +++++++++++-------- .../plugins/gitlab/util/gitLabStatistics.kt | 5 ++- 6 files changed, 47 insertions(+), 63 deletions(-) delete mode 100644 plugins/gitlab/gitlab-core/resources/graphql/query/mergeRequestCreate.graphql diff --git a/plugins/gitlab/gitlab-core/resources/graphql/query/mergeRequestCreate.graphql b/plugins/gitlab/gitlab-core/resources/graphql/query/mergeRequestCreate.graphql deleted file mode 100644 index 4398eaa444bf..000000000000 --- a/plugins/gitlab/gitlab-core/resources/graphql/query/mergeRequestCreate.graphql +++ /dev/null @@ -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 - } -} \ No newline at end of file diff --git a/plugins/gitlab/gitlab-core/src/org/jetbrains/plugins/gitlab/api/GitLabGQLQuery.kt b/plugins/gitlab/gitlab-core/src/org/jetbrains/plugins/gitlab/api/GitLabGQLQuery.kt index 55313bc8ef6b..765adb4c0e20 100644 --- a/plugins/gitlab/gitlab-core/src/org/jetbrains/plugins/gitlab/api/GitLabGQLQuery.kt +++ b/plugins/gitlab/gitlab-core/src/org/jetbrains/plugins/gitlab/api/GitLabGQLQuery.kt @@ -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") diff --git a/plugins/gitlab/gitlab-core/src/org/jetbrains/plugins/gitlab/api/request/GitLabProjectApi.kt b/plugins/gitlab/gitlab-core/src/org/jetbrains/plugins/gitlab/api/request/GitLabProjectApi.kt index c7f7d64ceef9..e2b6572b6dd3 100644 --- a/plugins/gitlab/gitlab-core/src/org/jetbrains/plugins/gitlab/api/request/GitLabProjectApi.kt +++ b/plugins/gitlab/gitlab-core/src/org/jetbrains/plugins/gitlab/api/request/GitLabProjectApi.kt @@ -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?> { - 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(request, "mergeRequestCreate") - } -} - private class LabelConnection(pageInfo: GraphQLCursorPageInfoDTO, nodes: List) : GraphQLConnectionDTO(pageInfo, nodes) private class WorkItemConnection(pageInfo: GraphQLCursorPageInfoDTO, nodes: List) - : GraphQLConnectionDTO(pageInfo, nodes) - -private class GitLabCreateMergeRequestResult( - mergeRequest: GitLabMergeRequestDTO, - errors: List?, - override val value: GitLabMergeRequestDTO = mergeRequest, -) : GitLabGraphQLMutationResultDTO(errors) \ No newline at end of file + : GraphQLConnectionDTO(pageInfo, nodes) \ No newline at end of file diff --git a/plugins/gitlab/gitlab-core/src/org/jetbrains/plugins/gitlab/mergerequest/api/request/GitLabMergeRequestsApi.kt b/plugins/gitlab/gitlab-core/src/org/jetbrains/plugins/gitlab/mergerequest/api/request/GitLabMergeRequestsApi.kt index 50b626995bde..865f6d6b9e57 100644 --- a/plugins/gitlab/gitlab-core/src/org/jetbrains/plugins/gitlab/mergerequest/api/request/GitLabMergeRequestsApi.kt +++ b/plugins/gitlab/gitlab-core/src/org/jetbrains/plugins/gitlab/mergerequest/api/request/GitLabMergeRequestsApi.kt @@ -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 { + 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 = diff --git a/plugins/gitlab/gitlab-core/src/org/jetbrains/plugins/gitlab/mergerequest/data/GitLabProject.kt b/plugins/gitlab/gitlab-core/src/org/jetbrains/plugins/gitlab/mergerequest/data/GitLabProject.kt index 693325cb75b1..ec8a1217bc47 100644 --- a/plugins/gitlab/gitlab-core/src/org/jetbrains/plugins/gitlab/mergerequest/data/GitLabProject.kt +++ b/plugins/gitlab/gitlab-core/src/org/jetbrains/plugins/gitlab/mergerequest/data/GitLabProject.kt @@ -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): 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() } diff --git a/plugins/gitlab/gitlab-core/src/org/jetbrains/plugins/gitlab/util/gitLabStatistics.kt b/plugins/gitlab/gitlab-core/src/org/jetbrains/plugins/gitlab/util/gitLabStatistics.kt index 6a7397302e18..f2770c5092ba 100644 --- a/plugins/gitlab/gitlab-core/src/org/jetbrains/plugins/gitlab/util/gitLabStatistics.kt +++ b/plugins/gitlab/gitlab-core/src/org/jetbrains/plugins/gitlab/util/gitLabStatistics.kt @@ -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