From f549a868fddb240815bf7bcdbee5a9c20f843ab1 Mon Sep 17 00:00:00 2001
From: Alessandro Manno <alessandromanno96@gmail.com>
Date: Mon, 16 Oct 2023 08:58:23 +0200
Subject: [PATCH] fix(platform/gitlab): double pipelines issue (#24500)

Co-authored-by: Sergei Zharinov <zharinov@users.noreply.github.com>
Co-authored-by: Rhys Arkins <rhys@arkins.net>
---
 lib/modules/platform/gitlab/index.spec.ts | 43 +++++++++++++++++++++++
 lib/modules/platform/gitlab/index.ts      | 12 +++++++
 lib/modules/platform/gitlab/schema.ts     |  9 +++++
 3 files changed, 64 insertions(+)
 create mode 100644 lib/modules/platform/gitlab/schema.ts

diff --git a/lib/modules/platform/gitlab/index.spec.ts b/lib/modules/platform/gitlab/index.spec.ts
index cfa104946e..5f3afefd29 100644
--- a/lib/modules/platform/gitlab/index.spec.ts
+++ b/lib/modules/platform/gitlab/index.spec.ts
@@ -928,6 +928,10 @@ describe('modules/platform/gitlab/index', () => {
         .get(
           '/api/v4/projects/some%2Frepo/repository/commits/0d9c7726c3d628b7e28af234595cfd20febdbf8e/statuses'
         )
+        .reply(200, [])
+        .get(
+          '/api/v4/projects/some%2Frepo/repository/commits/0d9c7726c3d628b7e28af234595cfd20febdbf8e'
+        )
         .reply(200, []);
 
       await expect(
@@ -951,6 +955,10 @@ describe('modules/platform/gitlab/index', () => {
         .get(
           '/api/v4/projects/some%2Frepo/repository/commits/0d9c7726c3d628b7e28af234595cfd20febdbf8e/statuses'
         )
+        .reply(200, [])
+        .get(
+          '/api/v4/projects/some%2Frepo/repository/commits/0d9c7726c3d628b7e28af234595cfd20febdbf8e'
+        )
         .reply(200, []);
 
       await gitlab.setBranchStatus({
@@ -965,6 +973,37 @@ describe('modules/platform/gitlab/index', () => {
       expect(timers.setTimeout.mock.calls[0][0]).toBe(1000);
     });
 
+    it('set branch status with pipeline_id', async () => {
+      const scope = await initRepo();
+      scope
+        .post(
+          '/api/v4/projects/some%2Frepo/statuses/0d9c7726c3d628b7e28af234595cfd20febdbf8e',
+          (body: any): boolean => {
+            expect(body.pipeline_id).toBe(123);
+            return true;
+          }
+        )
+        .reply(200, {})
+        .get(
+          '/api/v4/projects/some%2Frepo/repository/commits/0d9c7726c3d628b7e28af234595cfd20febdbf8e/statuses'
+        )
+        .reply(200, [])
+        .get(
+          '/api/v4/projects/some%2Frepo/repository/commits/0d9c7726c3d628b7e28af234595cfd20febdbf8e'
+        )
+        .reply(200, { last_pipeline: { id: 123 } });
+
+      await expect(
+        gitlab.setBranchStatus({
+          branchName: 'some-branch',
+          context: 'some-context',
+          description: 'some-description',
+          state: 'green',
+          url: 'some-url',
+        })
+      ).toResolve();
+    });
+
     it('waits for RENOVATE_X_GITLAB_BRANCH_STATUS_DELAY ms when set', async () => {
       const delay = 5000;
       process.env.RENOVATE_X_GITLAB_BRANCH_STATUS_DELAY = String(delay);
@@ -978,6 +1017,10 @@ describe('modules/platform/gitlab/index', () => {
         .get(
           '/api/v4/projects/some%2Frepo/repository/commits/0d9c7726c3d628b7e28af234595cfd20febdbf8e/statuses'
         )
+        .reply(200, [])
+        .get(
+          '/api/v4/projects/some%2Frepo/repository/commits/0d9c7726c3d628b7e28af234595cfd20febdbf8e'
+        )
         .reply(200, []);
 
       await gitlab.setBranchStatus({
diff --git a/lib/modules/platform/gitlab/index.ts b/lib/modules/platform/gitlab/index.ts
index 539fdb4dfa..27567a0f00 100644
--- a/lib/modules/platform/gitlab/index.ts
+++ b/lib/modules/platform/gitlab/index.ts
@@ -55,6 +55,7 @@ import { repoFingerprint } from '../util';
 import { smartTruncate } from '../utils/pr-body';
 import { getMemberUserIDs, getUserID, gitlabApi, isUserBusy } from './http';
 import { getMR, updateMR } from './merge-request';
+import { LastPipelineId } from './schema';
 import type {
   GitLabMergeRequest,
   GitlabComment,
@@ -912,9 +913,20 @@ export async function setBranchStatus({
     description,
     context,
   };
+
   if (targetUrl) {
     options.target_url = targetUrl;
   }
+
+  if (branchSha) {
+    const commitUrl = `projects/${config.repository}/repository/commits/${branchSha}`;
+    await gitlabApi
+      .getJsonSafe(commitUrl, LastPipelineId)
+      .onValue((pipelineId) => {
+        options.pipeline_id = pipelineId;
+      });
+  }
+
   try {
     // give gitlab some time to create pipelines for the sha
     await setTimeout(
diff --git a/lib/modules/platform/gitlab/schema.ts b/lib/modules/platform/gitlab/schema.ts
new file mode 100644
index 0000000000..b94b584be9
--- /dev/null
+++ b/lib/modules/platform/gitlab/schema.ts
@@ -0,0 +1,9 @@
+import { z } from 'zod';
+
+export const LastPipelineId = z
+  .object({
+    last_pipeline: z.object({
+      id: z.number(),
+    }),
+  })
+  .transform(({ last_pipeline }) => last_pipeline.id);
-- 
GitLab