diff --git a/lib/modules/platform/gitlab/__snapshots__/index.spec.ts.snap b/lib/modules/platform/gitlab/__snapshots__/index.spec.ts.snap index a0082574098a51647fcda0a7d016d0c5a8051906..7d0bdd4c0054856d7a1ea9ccaf9b4e8bccf67ed8 100644 --- a/lib/modules/platform/gitlab/__snapshots__/index.spec.ts.snap +++ b/lib/modules/platform/gitlab/__snapshots__/index.spec.ts.snap @@ -68,6 +68,7 @@ exports[`modules/platform/gitlab/index getBranchPr(branchName) should return the "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", }, "hasAssignees": false, + "headPipelineSha": undefined, "headPipelineStatus": undefined, "labels": undefined, "number": 91, @@ -86,6 +87,7 @@ exports[`modules/platform/gitlab/index getBranchPr(branchName) should strip depr "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", }, "hasAssignees": false, + "headPipelineSha": undefined, "headPipelineStatus": undefined, "isDraft": true, "labels": undefined, @@ -105,6 +107,7 @@ exports[`modules/platform/gitlab/index getBranchPr(branchName) should strip draf "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", }, "hasAssignees": false, + "headPipelineSha": undefined, "headPipelineStatus": undefined, "isDraft": true, "labels": undefined, @@ -124,6 +127,7 @@ exports[`modules/platform/gitlab/index getPr(prNo) removes deprecated draft pref "hash": "23f41dbec0785a6c77457dd6ebf99ae5970c5fffc9f7a8ad7f66c1b8eeba5b90", }, "hasAssignees": false, + "headPipelineSha": undefined, "headPipelineStatus": undefined, "isDraft": true, "labels": undefined, @@ -143,6 +147,7 @@ exports[`modules/platform/gitlab/index getPr(prNo) removes draft prefix from ret "hash": "23f41dbec0785a6c77457dd6ebf99ae5970c5fffc9f7a8ad7f66c1b8eeba5b90", }, "hasAssignees": false, + "headPipelineSha": undefined, "headPipelineStatus": undefined, "isDraft": true, "labels": undefined, @@ -162,6 +167,7 @@ exports[`modules/platform/gitlab/index getPr(prNo) returns the PR 1`] = ` "hash": "23f41dbec0785a6c77457dd6ebf99ae5970c5fffc9f7a8ad7f66c1b8eeba5b90", }, "hasAssignees": false, + "headPipelineSha": undefined, "headPipelineStatus": undefined, "labels": undefined, "number": 12345, @@ -180,6 +186,7 @@ exports[`modules/platform/gitlab/index getPr(prNo) returns the PR with nonexisti "hash": "23f41dbec0785a6c77457dd6ebf99ae5970c5fffc9f7a8ad7f66c1b8eeba5b90", }, "hasAssignees": true, + "headPipelineSha": undefined, "headPipelineStatus": undefined, "labels": undefined, "number": 12345, @@ -198,6 +205,7 @@ exports[`modules/platform/gitlab/index getPr(prNo) returns the mergeable PR 1`] "hash": "23f41dbec0785a6c77457dd6ebf99ae5970c5fffc9f7a8ad7f66c1b8eeba5b90", }, "hasAssignees": true, + "headPipelineSha": undefined, "headPipelineStatus": undefined, "labels": undefined, "number": 12345, diff --git a/lib/modules/platform/gitlab/index.spec.ts b/lib/modules/platform/gitlab/index.spec.ts index 671e64080280d86d37a66838063887272296fde6..1fc1fce268550a0e05e7fa9f712da700bb2975c2 100644 --- a/lib/modules/platform/gitlab/index.spec.ts +++ b/lib/modules/platform/gitlab/index.spec.ts @@ -652,7 +652,7 @@ describe('modules/platform/gitlab/index', () => { expect(res).toBe('yellow'); }); - it('returns success if no results but head pipeline success', async () => { + it('returns success if no results with merged results pipeline success', async () => { const scope = await initRepo(); scope .get( @@ -688,7 +688,9 @@ describe('modules/platform/gitlab/index', () => { }, head_pipeline: { status: 'success', + sha: 'abcd', }, + sha: 'defg', }); const res = await gitlab.getBranchStatus('some-branch', true); expect(res).toBe('green'); @@ -730,6 +732,140 @@ describe('modules/platform/gitlab/index', () => { expect(res).toBe('yellow'); }); + it('returns pending if merge request with no pipelines', 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', + }, + sha: 'abcd', + }); + const res = await gitlab.getBranchStatus('some-branch', false); + expect(res).toBe('yellow'); + }); + + it('returns pending if all are internal success with no merged results pipeline', async () => { + const scope = await initRepo(); + scope + .get( + '/api/v4/projects/some%2Frepo/repository/commits/0d9c7726c3d628b7e28af234595cfd20febdbf8e/statuses', + ) + .reply(200, [ + { name: 'renovate/stability-days', status: 'success' }, + { name: 'renovate/other', status: 'success' }, + ]) + .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', + sha: 'abcd', + }, + sha: 'abcd', + }); + const res = await gitlab.getBranchStatus('some-branch', false); + expect(res).toBe('yellow'); + }); + + it('returns success if all are internal success with merged results pipeline success', async () => { + const scope = await initRepo(); + scope + .get( + '/api/v4/projects/some%2Frepo/repository/commits/0d9c7726c3d628b7e28af234595cfd20febdbf8e/statuses', + ) + .reply(200, [ + { name: 'renovate/stability-days', status: 'success' }, + { name: 'renovate/other', status: 'success' }, + ]) + .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', + sha: 'defg', + }, + sha: 'abcd', + }); + const res = await gitlab.getBranchStatus('some-branch', false); + expect(res).toBe('green'); + }); + it('returns success if optional jobs fail', async () => { const scope = await initRepo(); scope @@ -2785,6 +2921,7 @@ describe('modules/platform/gitlab/index', () => { }, hasAssignees: false, headPipelineStatus: undefined, + headPipelineSha: undefined, labels: undefined, number: 12345, reviewers: ['foo', 'bar'], diff --git a/lib/modules/platform/gitlab/index.ts b/lib/modules/platform/gitlab/index.ts index 264a05bb10b7eda255fa7347973777d93aae1e2b..de544f48cce3e087570e5ed8573da2be1727a1b4 100644 --- a/lib/modules/platform/gitlab/index.ts +++ b/lib/modules/platform/gitlab/index.ts @@ -482,10 +482,13 @@ export async function getBranchStatus( } logger.debug(`Got res with ${branchStatuses.length} results`); - const mrStatus = (await getBranchPr(branchName))?.headPipelineStatus; - if (!is.undefined(mrStatus)) { + const mr = await getBranchPr(branchName); + if (mr && mr.sha !== mr.headPipelineSha && mr.headPipelineStatus) { + logger.debug( + 'Merge request head pipeline has different sha to commit, assuming merged results pipeline', + ); branchStatuses.push({ - status: mrStatus as BranchState, + status: mr.headPipelineStatus as BranchState, name: 'head_pipeline', }); } @@ -804,6 +807,7 @@ export async function getPr(iid: number): Promise<GitlabPr> { bodyStruct: getPrBodyStruct(mr.description), state: mr.state === 'opened' ? 'open' : mr.state, headPipelineStatus: mr.head_pipeline?.status, + headPipelineSha: mr.head_pipeline?.sha, hasAssignees: !!(mr.assignee?.id ?? mr.assignees?.[0]?.id), reviewers: mr.reviewers?.map(({ username }) => username), title: mr.title, diff --git a/lib/modules/platform/gitlab/types.ts b/lib/modules/platform/gitlab/types.ts index 897d25175783b455ffcb594cc762ac0f2517d6d0..244ec8366361e6b7d713ec84a15b72177c5c1bd4 100644 --- a/lib/modules/platform/gitlab/types.ts +++ b/lib/modules/platform/gitlab/types.ts @@ -35,11 +35,13 @@ export interface GitLabMergeRequest { sha: LongCommitSha; head_pipeline?: { status: string; + sha: string; }; } export interface GitlabPr extends Pr { headPipelineStatus?: string; + headPipelineSha?: string; } export interface UpdateMergeRequest {