From bcb6076bc67279ac451d5d0d3449bbc89c4830d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20H=C3=B6ppner?= <jonas.hoeppner@garz-fricke.com> Date: Fri, 6 May 2022 14:23:25 +0200 Subject: [PATCH] CI: Add check if integration branch is on top of target branch before reusing it The integration branch was reused even if there where new commits on the target branch, which could lead into reverting some changes. This adds a check, if the existing integration branch is directly based on the target branch and deletes it if not. --- .gitlab-ci.yml | 1 + check_if_integration_branch_is_up_to_date.py | 2 +- common.py | 10 +++- deploy_gitlab_ci.py | 3 +- update_submodule.py | 51 +++++++++++++------- 5 files changed, 46 insertions(+), 21 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index ce94903..2046a68 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -116,6 +116,7 @@ yamllint: --manifest-project=${MANIFEST_PROJECT} --submodule=.gitlab-ci --revision=${CI_COMMIT_SHA} + --verbose ${MERGE} ${INTEGRATE_INTO} diff --git a/check_if_integration_branch_is_up_to_date.py b/check_if_integration_branch_is_up_to_date.py index 460f331..42c2605 100755 --- a/check_if_integration_branch_is_up_to_date.py +++ b/check_if_integration_branch_is_up_to_date.py @@ -53,7 +53,7 @@ def check_if_integration_branch_is_up_to_date( # Loop over the commits until the integration_branch head id is found return common.is_commit_parent_of_project_commit( - manifest_project, integration_branch.commit["id"], integration_base_id + manifest_project, integration_branch.commit["id"], integration_base_id, limit=10 ) diff --git a/common.py b/common.py index 599ae3b..6e45da0 100755 --- a/common.py +++ b/common.py @@ -266,7 +266,9 @@ def get_repository_file_obj(project: Project, filename, ref=None): return fileobj -def is_commit_parent_of_project_commit(project: Project, project_commit, commit): +def is_commit_parent_of_project_commit( + project: Project, project_commit, commit, limit=None +): """Walks through the commits of project, starting with project_commit and compares its sha with the given commit. Both commits are specified as sha @@ -280,7 +282,13 @@ def is_commit_parent_of_project_commit(project: Project, project_commit, commit) # Loop over the parent commits until commit is found parent_id = project_commit + count = 0 while True: + count = count + 1 + if limit is not None and count >= limit: + logging.debug("Check %d commits and did not found a match.", count) + return False + try: parent = project.commits.get(parent_id, retry_transient_errors=True) except GitlabGetError as e: diff --git a/deploy_gitlab_ci.py b/deploy_gitlab_ci.py index 127630c..2e52073 100755 --- a/deploy_gitlab_ci.py +++ b/deploy_gitlab_ci.py @@ -185,7 +185,7 @@ def main(): project_integration = {} # Update submodule in all 'child' project for p in args.projects: - logging.debug("Integrate into: %s", p) + print("Create integration commit is: %s", p) res = integrate_submodule_into( gitlab, p, args.submodule, args.revision, args.branch @@ -195,6 +195,7 @@ def main(): if res["commit"] is not None: project_integration[p] = res + print("Create integration commit in: %s", args.project) # Update submodule in manifest project manifest_project = integrate_submodule_into( gitlab, diff --git a/update_submodule.py b/update_submodule.py index 1103d91..6c3f760 100755 --- a/update_submodule.py +++ b/update_submodule.py @@ -282,25 +282,40 @@ def update_submodule_and_include_ref( pass if existing_branch: - ( - _, - integration_branch_submodule_rev, - ) = get_submodule_project_path_and_revision( - project, submodule_name, integration_branch_name - ) - logging.debug( - "Revision in integration branch '%s', new_revision '%s'", - integration_branch_submodule_rev, - new_revision, - ) - - if integration_branch_submodule_rev == new_revision: - print( - "Submodule is already at %s on branch %s" - % (new_revision, integration_branch_name) + # Check if the integration branch is on top of the integration + # base or if it is outdated + integration_base_branch = project.branches.get(branch) + integration_base_id = integration_base_branch.commit["id"] + logging.debug("Head of %s points to %s", branch, integration_base_id) + + # Loop over the commits until the integration_branch head id is found + if not common.is_commit_parent_of_project_commit( + project, existing_branch.commit["id"], integration_base_id, limit=5 + ): + logging.debug("Integration branch is outdated, delete it.") + project.branches.delete(existing_branch.name) + existing_branch = None + else: + # Check the submodule revision on the integration branch + ( + _, + integration_branch_submodule_rev, + ) = get_submodule_project_path_and_revision( + project, submodule_name, integration_branch_name ) - integration_commit = existing_branch.commit["id"] - submodule_update_needed = False + logging.debug( + "Revision in integration branch '%s', new_revision '%s'", + integration_branch_submodule_rev, + new_revision, + ) + + if integration_branch_submodule_rev == new_revision: + print( + "Submodule is already at %s on branch %s" + % (new_revision, integration_branch_name) + ) + integration_commit = existing_branch.commit["id"] + submodule_update_needed = False # Clone the project, we need to do changes if submodule_update_needed or force_clone: -- GitLab