From 100cb2143a03b5bfd7c3362d1d244e6d746f58fb Mon Sep 17 00:00:00 2001
From: Tim Jaacks <tim.jaacks@garz-fricke.com>
Date: Mon, 14 Jun 2021 16:10:55 +0200
Subject: [PATCH] merge_into_manifest: add merge_status check before merge
 attempt

We had some cases where the merge job added rebases of a commit where rebasing
was not necessary at all, e.g.:
https://gitlab.com/garz-fricke/yocto/layers/meta-guf-machine/-/jobs/1270293595

This is obviously a known issue in GitLab concerning the HTTP return value of
the merge endpoint:
https://gitlab.com/gitlab-org/gitlab/-/issues/196962

Suggested workaround is to manually check merge_status and wait until it is
ready before attempting to merge the MR.
---
 merge_into_manifest.py | 17 ++++++++++++++++-
 1 file changed, 16 insertions(+), 1 deletion(-)

diff --git a/merge_into_manifest.py b/merge_into_manifest.py
index a57124ab..b5e482f0 100755
--- a/merge_into_manifest.py
+++ b/merge_into_manifest.py
@@ -3,6 +3,7 @@ import common
 
 import argparse
 import sys
+import time
 from gitlab import (
     Gitlab,
     GitlabGetError,
@@ -76,12 +77,25 @@ def merge_into_manifest(manifest_project, master_branch, project, commit):
     mr.notes.create({"body": "Source merge request: %s" % source_mr.web_url})
     source_mr.notes.create({"body": "Integration merge request: %s" % mr.web_url})
 
-    # Attempt to merge, reintegrate if necessary
+    # Loop until MR has been merged successfully
     manifest_revision = mr.sha
     merged = False
     while not merged:
+
+        # Wait until GitLab has checked merge status
+        print("Waiting until merge status has been checked", end="", flush=True)
+        unchecked_states = ["unchecked", "checking", "cannot_be_merged_recheck"]
+        while mr.merge_status in unchecked_states:
+            print(".", end="", flush=True)
+            time.sleep(1)
+            mr = manifest_project.mergerequests.get(mr.iid)
+        print("")
+
+        # Attempt to merge
         merged = accept_merge_request(manifest_project, mr)
+
         if not merged:
+            # Merge failed, reintegrate the source merge request into the manifest.
             # Note: if reintegration is necessary here, the source merge request was
             # merged without running the pipeline on the latest manifest, i.e. some
             # other project has been merged in between. Automatic rebase is not
@@ -97,6 +111,7 @@ def merge_into_manifest(manifest_project, master_branch, project, commit):
                 project=project,
                 merge_request=source_mr,
             )
+            mr = manifest_project.mergerequests.get(mr.iid)
 
     print("Successfully merged")
 
-- 
GitLab