From 2567d52b5bbe28a78a4859defde2c1fcaa0ea47c Mon Sep 17 00:00:00 2001 From: Sergei Shmakov Date: Fri, 22 Nov 2024 19:00:40 +0100 Subject: [PATCH] Implements pull request search to GitLab integration using GitLab's API (#3788, #3795) --- src/plus/integrations/providers/gitlab.ts | 23 ++++++++++ .../integrations/providers/gitlab/gitlab.ts | 44 +++++++++++++++++++ .../integrations/providers/gitlab/models.ts | 14 +++++- 3 files changed, 79 insertions(+), 2 deletions(-) diff --git a/src/plus/integrations/providers/gitlab.ts b/src/plus/integrations/providers/gitlab.ts index 9353999254412..3eb7a8404e026 100644 --- a/src/plus/integrations/providers/gitlab.ts +++ b/src/plus/integrations/providers/gitlab.ts @@ -312,6 +312,29 @@ abstract class GitLabIntegrationBase< .filter((result): result is SearchedIssue => result != null); } + protected override async searchProviderPullRequests( + { accessToken }: AuthenticationSession, + searchQuery: string, + repos?: GitLabRepositoryDescriptor[], + cancellation?: CancellationToken, + ): Promise { + const api = await this.container.gitlab; + if (!api) { + return undefined; + } + + return api.searchPullRequests( + this, + accessToken, + { + search: searchQuery, + repos: repos?.map(r => `${r.owner}/${r.name}`), + baseUrl: this.apiBaseUrl, + }, + cancellation, + ); + } + protected override async mergeProviderPullRequest( _session: AuthenticationSession, pr: PullRequest, diff --git a/src/plus/integrations/providers/gitlab/gitlab.ts b/src/plus/integrations/providers/gitlab/gitlab.ts index 81a8b71db9796..46021a9628529 100644 --- a/src/plus/integrations/providers/gitlab/gitlab.ts +++ b/src/plus/integrations/providers/gitlab/gitlab.ts @@ -661,6 +661,50 @@ export class GitLabApi implements Disposable { } } + @debug({ args: { 0: p => p.name, 1: '' } }) + async searchPullRequests( + provider: Provider, + token: string, + options?: { search?: string; user?: string; repos?: string[]; baseUrl?: string; avatarSize?: number }, + cancellation?: CancellationToken, + ): Promise { + const scope = getLogScope(); + const search = options?.search; + if (!search) { + return []; + } + try { + const gitlabPRs = await this.request( + provider, + token, + options?.baseUrl, + `v4/search/?scope=merge_requests&search=${search}`, + { + method: 'GET', + }, + cancellation, + scope, + ); + if (gitlabPRs.length === 0) { + return []; + } + + const prs: PullRequest[] = gitlabPRs.map(pr => { + const fullRef = pr.references.full; + const project = { + owner: fullRef.substring(0, fullRef.lastIndexOf('/')), + repo: fullRef.substring(fullRef.lastIndexOf('/') + 1, fullRef.lastIndexOf('!')), + }; + return fromGitLabMergeRequestREST(pr, provider, project); + }); + return prs; + } catch (ex) { + if (ex instanceof RequestNotFoundError) return []; + + throw this.handleException(ex, provider, scope); + } + } + private async findUser( provider: Provider, token: string, diff --git a/src/plus/integrations/providers/gitlab/models.ts b/src/plus/integrations/providers/gitlab/models.ts index 86a6f16a39b1c..be86578ff073c 100644 --- a/src/plus/integrations/providers/gitlab/models.ts +++ b/src/plus/integrations/providers/gitlab/models.ts @@ -1,6 +1,6 @@ import { HostingIntegrationId } from '../../../../constants.integrations'; import type { PullRequestState } from '../../../../git/models/pullRequest'; -import { PullRequest } from '../../../../git/models/pullRequest'; +import { PullRequest, PullRequestMergeableState } from '../../../../git/models/pullRequest'; import type { PullRequestUrlIdentity } from '../../../../git/models/pullRequest.utils'; import type { Provider } from '../../../../git/models/remoteProvider'; import type { Integration } from '../../integration'; @@ -93,7 +93,12 @@ export interface GitLabMergeRequestREST { updated_at: string; closed_at: string | null; merged_at: string | null; + detailed_merge_status: 'conflict' | 'mergeable' | string; // https://docs.gitlab.com/ee/api/merge_requests.html#merge-status web_url: string; + references: { + full: string; + short: string; + }; } export function fromGitLabMergeRequestREST( @@ -110,7 +115,7 @@ export function fromGitLabMergeRequestREST( url: pr.author?.web_url ?? '', }, String(pr.iid), - undefined, + String(pr.id), pr.title, pr.web_url, repo, @@ -119,6 +124,11 @@ export function fromGitLabMergeRequestREST( new Date(pr.updated_at), pr.closed_at == null ? undefined : new Date(pr.closed_at), pr.merged_at == null ? undefined : new Date(pr.merged_at), + pr.detailed_merge_status === 'mergeable' + ? PullRequestMergeableState.Mergeable + : pr.detailed_merge_status === 'conflict' + ? PullRequestMergeableState.Conflicting + : PullRequestMergeableState.Unknown, ); }