From 56c61c962f8d5588a73b559f15f6e4d5ed76665d Mon Sep 17 00:00:00 2001 From: Gabriel Bleu <box.gbleu@gmail.com> Date: Tue, 6 Sep 2022 09:09:58 +0200 Subject: [PATCH] feat(gitlab): handle merge results pipelines (#17440) (#17601) --- .../gitlab/__snapshots__/index.spec.ts.snap | 8 ++ lib/modules/platform/gitlab/index.spec.ts | 94 +++++++++++++++++-- lib/modules/platform/gitlab/index.ts | 18 +++- lib/modules/platform/gitlab/types.ts | 9 ++ 4 files changed, 118 insertions(+), 11 deletions(-) diff --git a/lib/modules/platform/gitlab/__snapshots__/index.spec.ts.snap b/lib/modules/platform/gitlab/__snapshots__/index.spec.ts.snap index 105a60c134..5aa3de2cc3 100644 --- a/lib/modules/platform/gitlab/__snapshots__/index.spec.ts.snap +++ b/lib/modules/platform/gitlab/__snapshots__/index.spec.ts.snap @@ -76,6 +76,7 @@ exports[`modules/platform/gitlab/index getBranchPr(branchName) should return the "displayNumber": "Merge Request #91", "hasAssignees": false, "hasReviewers": false, + "headPipelineStatus": undefined, "labels": undefined, "number": 91, "sha": undefined, @@ -94,6 +95,7 @@ exports[`modules/platform/gitlab/index getBranchPr(branchName) should strip depr "displayNumber": "Merge Request #91", "hasAssignees": false, "hasReviewers": false, + "headPipelineStatus": undefined, "isDraft": true, "labels": undefined, "number": 91, @@ -113,6 +115,7 @@ exports[`modules/platform/gitlab/index getBranchPr(branchName) should strip draf "displayNumber": "Merge Request #91", "hasAssignees": false, "hasReviewers": false, + "headPipelineStatus": undefined, "isDraft": true, "labels": undefined, "number": 91, @@ -132,6 +135,7 @@ exports[`modules/platform/gitlab/index getPr(prNo) removes deprecated draft pref "displayNumber": "Merge Request #12345", "hasAssignees": false, "hasReviewers": false, + "headPipelineStatus": undefined, "isDraft": true, "labels": undefined, "number": 12345, @@ -151,6 +155,7 @@ exports[`modules/platform/gitlab/index getPr(prNo) removes draft prefix from ret "displayNumber": "Merge Request #12345", "hasAssignees": false, "hasReviewers": false, + "headPipelineStatus": undefined, "isDraft": true, "labels": undefined, "number": 12345, @@ -170,6 +175,7 @@ exports[`modules/platform/gitlab/index getPr(prNo) returns the PR 1`] = ` "displayNumber": "Merge Request #12345", "hasAssignees": false, "hasReviewers": false, + "headPipelineStatus": undefined, "labels": undefined, "number": 12345, "sha": undefined, @@ -188,6 +194,7 @@ exports[`modules/platform/gitlab/index getPr(prNo) returns the PR with nonexisti "displayNumber": "Merge Request #12345", "hasAssignees": true, "hasReviewers": false, + "headPipelineStatus": undefined, "labels": undefined, "number": 12345, "sha": undefined, @@ -206,6 +213,7 @@ exports[`modules/platform/gitlab/index getPr(prNo) returns the mergeable PR 1`] "displayNumber": "Merge Request #12345", "hasAssignees": true, "hasReviewers": false, + "headPipelineStatus": undefined, "labels": undefined, "number": 12345, "sha": undefined, diff --git a/lib/modules/platform/gitlab/index.spec.ts b/lib/modules/platform/gitlab/index.spec.ts index 74f6fe779c..db0391e924 100644 --- a/lib/modules/platform/gitlab/index.spec.ts +++ b/lib/modules/platform/gitlab/index.spec.ts @@ -527,18 +527,68 @@ describe('modules/platform/gitlab/index', () => { .get( '/api/v4/projects/some%2Frepo/repository/commits/0d9c7726c3d628b7e28af234595cfd20febdbf8e/statuses' ) + .reply(200, []) + .get( + '/api/v4/projects/some%2Frepo/merge_requests?per_page=100&scope=created_by_me' + ) .reply(200, []); const res = await gitlab.getBranchStatus('somebranch'); expect(res).toEqual(BranchStatus.yellow); }); + it('returns success if no results but head pipeline success', async () => { + const scope = await initRepo(); + scope + .get( + '/api/v4/projects/some%2Frepo/repository/commits/0d9c7726c3d628b7e28af234595cfd20febdbf8e/statuses' + ) + .reply(200, []) + .get( + '/api/v4/projects/some%2Frepo/merge_requests?per_page=100&scope=created_by_me' + ) + .reply(200, [ + { + iid: 91, + title: 'some change', + source_branch: 'some-branch', + target_branch: 'master', + state: 'opened', + }, + ]) + .get( + '/api/v4/projects/some%2Frepo/merge_requests/91?include_diverged_commits_count=1' + ) + .reply(200, { + iid: 91, + title: 'some change', + state: 'opened', + additions: 1, + deletions: 1, + commits: 1, + source_branch: 'some-branch', + target_branch: 'master', + base: { + sha: '1234', + }, + head_pipeline: { + status: 'success', + }, + }); + const res = await gitlab.getBranchStatus('some-branch'); + expect(res).toEqual(BranchStatus.green); + }); + it('returns success if all are success', async () => { const scope = await initRepo(); scope .get( '/api/v4/projects/some%2Frepo/repository/commits/0d9c7726c3d628b7e28af234595cfd20febdbf8e/statuses' ) - .reply(200, [{ status: 'success' }, { status: 'success' }]); + .reply(200, [{ status: 'success' }, { status: 'success' }]) + .get( + '/api/v4/projects/some%2Frepo/merge_requests?per_page=100&scope=created_by_me' + ) + .reply(200, []); const res = await gitlab.getBranchStatus('somebranch'); expect(res).toEqual(BranchStatus.green); }); @@ -552,7 +602,11 @@ describe('modules/platform/gitlab/index', () => { .reply(200, [ { status: 'success' }, { status: 'failed', allow_failure: true }, - ]); + ]) + .get( + '/api/v4/projects/some%2Frepo/merge_requests?per_page=100&scope=created_by_me' + ) + .reply(200, []); const res = await gitlab.getBranchStatus('somebranch'); expect(res).toEqual(BranchStatus.green); }); @@ -563,7 +617,11 @@ describe('modules/platform/gitlab/index', () => { .get( '/api/v4/projects/some%2Frepo/repository/commits/0d9c7726c3d628b7e28af234595cfd20febdbf8e/statuses' ) - .reply(200, [{ status: 'failed', allow_failure: true }]); + .reply(200, [{ status: 'failed', allow_failure: true }]) + .get( + '/api/v4/projects/some%2Frepo/merge_requests?per_page=100&scope=created_by_me' + ) + .reply(200, []); const res = await gitlab.getBranchStatus('somebranch'); expect(res).toEqual(BranchStatus.green); }); @@ -574,7 +632,11 @@ describe('modules/platform/gitlab/index', () => { .get( '/api/v4/projects/some%2Frepo/repository/commits/0d9c7726c3d628b7e28af234595cfd20febdbf8e/statuses' ) - .reply(200, [{ status: 'success' }, { status: 'skipped' }]); + .reply(200, [{ status: 'success' }, { status: 'skipped' }]) + .get( + '/api/v4/projects/some%2Frepo/merge_requests?per_page=100&scope=created_by_me' + ) + .reply(200, []); const res = await gitlab.getBranchStatus('somebranch'); expect(res).toEqual(BranchStatus.green); }); @@ -585,7 +647,11 @@ describe('modules/platform/gitlab/index', () => { .get( '/api/v4/projects/some%2Frepo/repository/commits/0d9c7726c3d628b7e28af234595cfd20febdbf8e/statuses' ) - .reply(200, [{ status: 'skipped' }]); + .reply(200, [{ status: 'skipped' }]) + .get( + '/api/v4/projects/some%2Frepo/merge_requests?per_page=100&scope=created_by_me' + ) + .reply(200, []); const res = await gitlab.getBranchStatus('somebranch'); expect(res).toEqual(BranchStatus.yellow); }); @@ -596,7 +662,11 @@ describe('modules/platform/gitlab/index', () => { .get( '/api/v4/projects/some%2Frepo/repository/commits/0d9c7726c3d628b7e28af234595cfd20febdbf8e/statuses' ) - .reply(200, [{ status: 'skipped' }, { status: 'failed' }]); + .reply(200, [{ status: 'skipped' }, { status: 'failed' }]) + .get( + '/api/v4/projects/some%2Frepo/merge_requests?per_page=100&scope=created_by_me' + ) + .reply(200, []); const res = await gitlab.getBranchStatus('somebranch'); expect(res).toEqual(BranchStatus.red); }); @@ -611,7 +681,11 @@ describe('modules/platform/gitlab/index', () => { { status: 'success' }, { status: 'failed', allow_failure: true }, { status: 'failed' }, - ]); + ]) + .get( + '/api/v4/projects/some%2Frepo/merge_requests?per_page=100&scope=created_by_me' + ) + .reply(200, []); const res = await gitlab.getBranchStatus('somebranch'); expect(res).toEqual(BranchStatus.red); }); @@ -622,7 +696,11 @@ describe('modules/platform/gitlab/index', () => { .get( '/api/v4/projects/some%2Frepo/repository/commits/0d9c7726c3d628b7e28af234595cfd20febdbf8e/statuses' ) - .reply(200, [{ status: 'success' }, { status: 'foo' }]); + .reply(200, [{ status: 'success' }, { status: 'foo' }]) + .get( + '/api/v4/projects/some%2Frepo/merge_requests?per_page=100&scope=created_by_me' + ) + .reply(200, []); const res = await gitlab.getBranchStatus('somebranch'); expect(res).toEqual(BranchStatus.yellow); }); diff --git a/lib/modules/platform/gitlab/index.ts b/lib/modules/platform/gitlab/index.ts index 94f89233a4..2069b99948 100644 --- a/lib/modules/platform/gitlab/index.ts +++ b/lib/modules/platform/gitlab/index.ts @@ -57,6 +57,7 @@ import type { GitLabMergeRequest, GitlabComment, GitlabIssue, + GitlabPr, MergeMethod, RepoResponse, } from './types'; @@ -414,6 +415,14 @@ export async function getBranchStatus( return BranchStatus.yellow; } logger.debug(`Got res with ${branchStatuses.length} results`); + + const mrStatus = (await getBranchPr(branchName))?.headPipelineStatus; + if (!is.undefined(mrStatus)) { + branchStatuses.push({ + status: mrStatus as BranchState, + name: 'head_pipeline', + }); + } // ignore all skipped jobs const res = branchStatuses.filter((check) => check.status !== 'skipped'); if (res.length === 0) { @@ -606,18 +615,19 @@ export async function createPr({ return massagePr(pr); } -export async function getPr(iid: number): Promise<Pr> { +export async function getPr(iid: number): Promise<GitlabPr> { logger.debug(`getPr(${iid})`); const mr = await getMR(config.repository, iid); // Harmonize fields with GitHub - const pr: Pr = { + const pr: GitlabPr = { sourceBranch: mr.source_branch, targetBranch: mr.target_branch, number: mr.iid, displayNumber: `Merge Request #${mr.iid}`, bodyStruct: getPrBodyStruct(mr.description), state: mr.state === 'opened' ? PrState.Open : mr.state, + headPipelineStatus: mr.head_pipeline?.status, hasAssignees: !!(mr.assignee?.id ?? mr.assignees?.[0]?.id), hasReviewers: !!mr.reviewers?.length, title: mr.title, @@ -734,7 +744,9 @@ export async function findPr({ } // Returns the Pull Request for a branch. Null if not exists. -export async function getBranchPr(branchName: string): Promise<Pr | null> { +export async function getBranchPr( + branchName: string +): Promise<GitlabPr | null> { logger.debug(`getBranchPr(${branchName})`); const existingPr = await findPr({ branchName, diff --git a/lib/modules/platform/gitlab/types.ts b/lib/modules/platform/gitlab/types.ts index b7aa89d5f1..011b13d88f 100644 --- a/lib/modules/platform/gitlab/types.ts +++ b/lib/modules/platform/gitlab/types.ts @@ -1,3 +1,5 @@ +import type { Pr } from '../types'; + export interface GitlabIssue { iid: number; @@ -30,6 +32,13 @@ export interface GitLabMergeRequest { reviewers?: GitLabUser[]; labels: string[]; sha: string; + head_pipeline?: { + status: string; + }; +} + +export interface GitlabPr extends Pr { + headPipelineStatus?: string; } export interface UpdateMergeRequest { -- GitLab