From bb392f5037b495a3c9f7dfa3ea7b340cf0163754 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jonas=20H=C3=B6ppner?= <jonas.hoeppner@garz-fricke.com>
Date: Tue, 22 Mar 2022 09:01:27 +0100
Subject: [PATCH] CI: Rewrite check job python file to use gitlab api (no clone
 anymore)

For projects like the kernel the git checkout needs a log of time and
space. Directly using the gitlab api only loads the infomation needed.
---
 check_if_integration_branch_is_up_to_date.py | 98 +++++++++-----------
 1 file changed, 42 insertions(+), 56 deletions(-)

diff --git a/check_if_integration_branch_is_up_to_date.py b/check_if_integration_branch_is_up_to_date.py
index 664dc513..9b926ce8 100755
--- a/check_if_integration_branch_is_up_to_date.py
+++ b/check_if_integration_branch_is_up_to_date.py
@@ -3,10 +3,7 @@ import common
 
 import argparse
 import sys
-import tempfile
 import logging
-from furl import furl
-from git import GitCommandError, Repo
 from gitlab import Gitlab, GitlabGetError
 
 
@@ -16,59 +13,51 @@ def check_if_integration_branch_is_up_to_date(
     project,
     merge_request,
 ):
-    gitlab = manifest_project.manager.gitlab
 
-    with tempfile.TemporaryDirectory() as manifest_dir:
-
-        # Construct clone url containing access token
-        clone_url = furl(manifest_project.http_url_to_repo)
-        clone_url.username = "gitlab-ci"
-        clone_url.password = gitlab.private_token
-
-        # Checkout manifest
+    integration_branch = None
+    if merge_request.source_branch.startswith("integrate/gitlab-ci"):
         try:
-            manifest_repo = Repo.clone_from(
-                clone_url.url, manifest_dir, depth=1
+            integration_branch = manifest_project.branches.get(
+                merge_request.source_branch,
+                retry_transient_errors=True,
             )
-        except GitCommandError as e:
-            sys.exit("ERROR: could not clone manifest repository\n" + str(e))
-
 
-        # Handle gitlab-ci integration
-        integration_branch = common.find_gitlab_ci_integration_branch( 
-                manifest_repo, 
-                merge_request.source_branch
+        except GitlabGetError:
+            # Branch not found
+            pass
+    if integration_branch is None:
+        integration_branch_name = common.integration_branch_name(
+            project.name, merge_request.source_branch
         )
-        if integration_branch is None:
-            integration_branch = common.integration_branch_name(
-                project.name, merge_request.source_branch
+        try:
+            integration_branch = manifest_project.branches.get(
+                integration_branch_name,
+                retry_transient_errors=True,
             )
+        except GitlabGetError:
+            sys.exit("ERROR: could not find integration branch\n")
 
-        logging.debug("Checking integration branch: %s", integration_branch)
-        manifest_repo.git.checkout('-b', integration_branch, "origin/{}".format(integration_branch))
-
-        # Get branches
-        try:
-            integration_branch = manifest_repo.heads[integration_branch]
-        except IndexError:
-            sys.exit("ERROR: branch '%s' not found" % integration_branch)
-        try:
-            integration_base = manifest_repo.remote().refs[integration_base]
-        except IndexError:
-            sys.exit("ERROR: branch '%s' not found" % integration_base)
-
-        logging.debug("Checking integration base: %s", integration_base)
-        parent = integration_branch.commit.parents[0]
-        while True:
-            logging.debug("Parent of integration branch: %s", parent)
-            # The integration branch is up to date if its parent is the integration base
-            if parent == integration_base.commit:
-                logging.debug("Found match")
-                return True
-            if len(parent.parents) > 0:
-                parent = parent.parents[0]
-            else:
-                return False
+    try:
+        integration_base_branch = manifest_project.branches.get(
+            integration_base, retry_transient_errors=True
+        )
+    except GitlabGetError:
+        sys.exit("ERROR: could not find integration base branch\n")
+
+    integration_base_id = integration_base_branch.commit["id"]
+
+    parent = integration_branch.commit
+    parent = manifest_project.commits.get(parent["id"], retry_transient_errors=True)
+    # Loop over the commits until the integration_branch head id is found
+    while True:
+        # The integration branch is up to date if its parent is the integration base
+        logging.debug(parent.id)
+        if parent.id == integration_base_id:
+            return True
+        if len(parent.parent_ids) == 0:
+            break
+        parent_id = parent.parent_ids[0]  # Assume linear history
+        parent = manifest_project.commits.get(parent_id, retry_transient_errors=True)
 
     return False
 
@@ -132,12 +121,9 @@ def main():
     logging.debug(args)
     manifest_project = common.get_project(gitlab, args.manifest_project)
     project = common.get_project(gitlab, args.project)
-    merge_request = common.get_merge_request( project, args.merge_request)
+    merge_request = common.get_merge_request(project, args.merge_request)
     if merge_request is None:
-        sys.exit(
-            "ERROR: could not get %s  %s"
-            % (project.name, args.merge_request)
-        )
+        sys.exit("ERROR: could not get %s  %s" % (project.name, args.merge_request))
 
     if check_if_integration_branch_is_up_to_date(
         manifest_project=manifest_project,
@@ -147,9 +133,9 @@ def main():
     ):
         print("Integration branch is up to date.")
     else:
-        mr_url=merge_request.web_url + "/pipelines"
+        mr_url = merge_request.web_url + "/pipelines"
         if args.parent_merge_request is not None:
-            mr_url=args.parent_merge_request + "/pipelines"
+            mr_url = args.parent_merge_request + "/pipelines"
 
         sys.exit(
             "Integration branch is not up to date. Please re-run the MR pipeline:\n"
-- 
GitLab