From 61221f4b090ab23f1fc4e5f8fef350ad3d535589 Mon Sep 17 00:00:00 2001
From: t-kulmburg <89128736+t-kulmburg@users.noreply.github.com>
Date: Fri, 16 Jun 2023 09:34:18 +0200
Subject: [PATCH] fix(gitlab): gitLabIgnoreApprovals works with multiple
 approval rules (#22693)

Co-authored-by: Michael Kriese <michael.kriese@visualon.de>
---
 lib/modules/platform/gitlab/index.spec.ts | 68 +++++++++++++++++++++++
 lib/modules/platform/gitlab/index.ts      | 14 ++++-
 2 files changed, 81 insertions(+), 1 deletion(-)

diff --git a/lib/modules/platform/gitlab/index.spec.ts b/lib/modules/platform/gitlab/index.spec.ts
index 500e7ccb6b..75959e84d2 100644
--- a/lib/modules/platform/gitlab/index.spec.ts
+++ b/lib/modules/platform/gitlab/index.spec.ts
@@ -1770,6 +1770,74 @@ describe('modules/platform/gitlab/index', () => {
       });
     });
 
+    it('will remove rules of type regular, if such rules exist', async () => {
+      await initPlatform('13.3.6-ee');
+      httpMock
+        .scope(gitlabApiHost)
+        .post('/api/v4/projects/undefined/merge_requests')
+        .reply(200, {
+          id: 1,
+          iid: 12345,
+          title: 'some title',
+        })
+        .get('/api/v4/projects/undefined/merge_requests/12345')
+        .reply(200)
+        .get('/api/v4/projects/undefined/merge_requests/12345')
+        .reply(200, {
+          merge_status: 'can_be_merged',
+          pipeline: {
+            id: 29626725,
+            sha: '2be7ddb704c7b6b83732fdd5b9f09d5a397b5f8f',
+            ref: 'patch-28',
+            status: 'success',
+          },
+        })
+        .put('/api/v4/projects/undefined/merge_requests/12345/merge')
+        .reply(200)
+        .get('/api/v4/projects/undefined/merge_requests/12345/approval_rules')
+        .reply(200, [
+          {
+            name: 'RegularApproverRule',
+            rule_type: 'regular',
+            id: 50006,
+          },
+          {
+            name: 'AnotherRegularApproverRule',
+            rule_type: 'regular',
+            id: 50007,
+          },
+        ])
+        .delete(
+          '/api/v4/projects/undefined/merge_requests/12345/approval_rules/50006'
+        )
+        .reply(200)
+        .delete(
+          '/api/v4/projects/undefined/merge_requests/12345/approval_rules/50007'
+        )
+        .reply(200)
+        .post('/api/v4/projects/undefined/merge_requests/12345/approval_rules')
+        .reply(200);
+      expect(
+        await gitlab.createPr({
+          sourceBranch: 'some-branch',
+          targetBranch: 'master',
+          prTitle: 'some-title',
+          prBody: 'the-body',
+          labels: [],
+          platformOptions: {
+            usePlatformAutomerge: true,
+            gitLabIgnoreApprovals: true,
+          },
+        })
+      ).toStrictEqual({
+        id: 1,
+        iid: 12345,
+        number: 12345,
+        sourceBranch: 'some-branch',
+        title: 'some title',
+      });
+    });
+
     it('does not try to create already existing approval rule', async () => {
       await initPlatform('13.3.6-ee');
       httpMock
diff --git a/lib/modules/platform/gitlab/index.ts b/lib/modules/platform/gitlab/index.ts
index 17e6a49728..8817d5178d 100644
--- a/lib/modules/platform/gitlab/index.ts
+++ b/lib/modules/platform/gitlab/index.ts
@@ -538,9 +538,22 @@ async function ignoreApprovals(pr: number): Promise<void> {
       }[]
     >(url);
 
+    const ruleName = 'renovateIgnoreApprovals';
+
     const existingAnyApproverRule = rules?.find(
       ({ rule_type }) => rule_type === 'any_approver'
     );
+    const existingRegularApproverRules = rules?.filter(
+      ({ rule_type, name }) => rule_type !== 'any_approver' && name !== ruleName
+    );
+
+    if (existingRegularApproverRules?.length) {
+      await p.all(
+        existingRegularApproverRules.map((rule) => async (): Promise<void> => {
+          await gitlabApi.deleteJson(`${url}/${rule.id}`);
+        })
+      );
+    }
 
     if (existingAnyApproverRule) {
       await gitlabApi.putJson(`${url}/${existingAnyApproverRule.id}`, {
@@ -549,7 +562,6 @@ async function ignoreApprovals(pr: number): Promise<void> {
       return;
     }
 
-    const ruleName = 'renovateIgnoreApprovals';
     const zeroApproversRule = rules?.find(({ name }) => name === ruleName);
     if (!zeroApproversRule) {
       await gitlabApi.postJson(url, {
-- 
GitLab