From 586d86f8f83ad706e01ab3401b157d14dc434460 Mon Sep 17 00:00:00 2001 From: Lorenzo Pagliai <lorenzo.pagliai@seco.com> Date: Wed, 26 Jul 2023 15:37:43 +0200 Subject: [PATCH] [MR][CLEANUP] Insert script to perform MR cleanup * This script is necessary for all the open MRs that were created by the GitBot when performing meta-layers/manifest integration. Indeed, in case the source MR is closed, the integration one created by the Gitbot remains opened and shall be closed by hand. The script actually searches for this type of MRs, close them and delete the source branch. * This type of job is intended to be executed on a weekly schedule in order to clean week by week the MR in the Edgehog group. --- .gitlab-ci.yml | 22 ++++++++ scripts/close_merge_request.py | 93 ++++++++++++++++++++++++++++++++++ 2 files changed, 115 insertions(+) create mode 100644 scripts/close_merge_request.py diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 92cd375..091cd34 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -9,6 +9,10 @@ variables: CI_IMAGES_REV: latest CI_IMAGE_PYTHON: "${CI_IMAGES_PATH}/infrastructure/python3.9:${CI_IMAGES_REV}" CI_IMAGE_YOCTO: "secodocker/edgehog-builder:${CI_IMAGES_REV}" + CLOSE_MR_PROJECTS: + edgehog/layers/seco/meta-seco-imx + edgehog/layers/seco/meta-seco-rk + edgehog/seco-manifest image: "${CI_IMAGE_PYTHON}" @@ -17,6 +21,7 @@ default: - infrastructure stages: + - closeMR - analyze - integrate - merge @@ -26,6 +31,7 @@ workflow: rules: - if: $CI_MERGE_REQUEST_IID - if: $CI_COMMIT_BRANCH == "master" + - if: $CI_PIPELINE_SOURCE == "schedule" # --------------------------------------------------------------------------------------- # Stage: analyze @@ -62,6 +68,22 @@ executable: # script: # - yamllint -c .yamllint.yml *.yml .*.yml +closeMR: + timeout: 1h + stage: closeMR + rules: + - if: $CI_PIPELINE_SOURCE == "schedule" + script: + - PROJECT_ARGS="" + - for project in ${CLOSE_MR_PROJECTS}; do + PROJECT_ARGS="${PROJECT_ARGS} --project=$project"; + done + - echo ${PROJECT_ARGS} + - python3 scripts/close_merge_request.py + --gitlab-url=${CI_SERVER_URL} + --token=${GITBOT_TOKEN} + --group=${CI_PROJECT_ROOT_NAMESPACE} + ${PROJECT_ARGS} # --------------------------------------------------------------------------------------- # Stage: integrate diff --git a/scripts/close_merge_request.py b/scripts/close_merge_request.py new file mode 100644 index 0000000..de4a5b7 --- /dev/null +++ b/scripts/close_merge_request.py @@ -0,0 +1,93 @@ +#!/usr/bin/env python3 +import common + +import argparse +import gitlab +from datetime import datetime, timedelta + +def find_merge_requests_with_branch(project, branch_name): + merge_requests = project.mergerequests.list(state='opened') + matching_merge_requests = [] + + for mr in merge_requests: + if 'Integrate' in mr.title and branch_name in mr.title: + matching_merge_requests.append(mr) + + return matching_merge_requests + +def main(): + + parser = argparse.ArgumentParser() + parser.add_argument( + "--gitlab-url", + help="""URL to the GitLab instance""", + dest="gitlab_url", + required=True, + ) + parser.add_argument( + "--token", + help="""GitLab REST API private access token""", + dest="token", + required=True, + ) + parser.add_argument( + "--group", + help="""name of the GitLab group""", + dest="group", + required=True, + ) + parser.add_argument( + "--project", + help="""project to search for MR to be closed""", + dest="projects", + action="append", + required=True, + ) + + args, _ = parser.parse_known_args() + + gl = gitlab.Gitlab(args.gitlab_url, private_token=args.token) + group = gl.groups.get(args.group) + projects = args.projects + + # Get the date from one week ago + one_week_ago = datetime.now() - timedelta(days=7) + + closed_mrs = group.mergerequests.list(state='closed', updated_after=one_week_ago) + + for mr in closed_mrs: + print(f"These are the MRs that were closed in the last week") + print(f"Merge Request ID: {mr.id}") + print(f"Title: {mr.title}") + print(f"Source Branch: {mr.source_branch}") + print(f"Target Branch: {mr.target_branch}") + print(f"Author: {mr.author['name']}") + print(f"Closed At: {mr.closed_at}") + print("---") + + for mr in closed_mrs: + branch_name = mr.source_branch + + # Loop through projects to find matching open merge requests + for repo_name in projects: + repo = gl.projects.get(repo_name) + matching_merge_requests = find_merge_requests_with_branch(repo, branch_name) + + for open_mr in matching_merge_requests: + print(f"Closing MR: {open_mr.title} in {repo_name}") + try: + open_mr.state_event = 'close' + open_mr.save() + except: + print(f"Impossible to close MR, please check MR: {open_mr.title} in {repo_name}") + return 1 + + print(f"Deleting branch: {open_mr.source_branch}") + try: + repo.branches.delete(open_mr.source_branch) + except: + print(f"Impossible to delete the source branch") + return 1 + +if __name__ == "__main__": + main() -- GitLab