Home > Software engineering >  Write script for GitLab for automatic merge of Merge Request
Write script for GitLab for automatic merge of Merge Request

Time:11-07

I am trying to write a script to merge the merge requests which are open and have met the criteria of merge requests (which is achieved via settings).

So the only thing I want to do is, I want to write a CI yaml file which I will schedule to run every 30 minutes or so to check for open merge request and merge them if they can be merged.

Confusion One:

I am able to achieve this via writing multiple curl requests, but I am not sure how to make use of them one after another after their execution.

So, to check for the open merge requests, I will need the ID of the projects of a group, to get that I have a curl command which will provide me project ids and I am saving them in a file projectid.txt.

curl -s --location --request GET --header 'PRIVATE-TOKEN:<PRIVATE_TOKEN>' '$CI_API_V4_URL/groups/'$GROUPID'/projects'  | sed 's/,/\n/g' | grep -w "id" | awk -F ':' '{print $2}' | sed -s 's/{"id"//g' 

Now, Once I have all the project ids, I want to flow them into another curl command which is :

curl -s --location --request GET '$CI_API_V4_URL/projects/3/merge_requests?state=opened' --header 'PRIVATE-TOKEN:<PRIVATE_TOKEN>' | sed 's/,/\n/g' | grep -w "iid" | awk -F ':' '{print $2}' 

but if you see the above curl request, I am giving 3 manually to get the desired output.

But I want this curl command to automatically take every projectid present in every line of projectid.txt and execute it to the second curl command.. In this way I want a file which will display the open merge request project wise.

Once I get all these information, I want to merge the open merge requests which are valid and are ready to be merged (GitLab takes care of checking if they are ready to merge or not)

So, the only thing I need now is, to give input of projectid & merge request id in the another curl command which is a PUT request.

curl --location --request PUT '$CI_API_V4_URL/projects/3/merge_requests/26/merge' \
--header 'PRIVATE-TOKEN: <PRIVATE_TOKEN>'

Source: https://docs.gitlab.com/ee/api/merge_requests.html#accept-mr

If you see the above merge request, I need to provide project wise merge requests.. I am kind of confused on how it can be automated.

Also, Can you tell me if this is a correct way to make use of these many curl requests in my gitlab-ci.yml file to automate this? Is there any other way to do it via Python or shell script?

Also, Is there any easy way to write python scripts with the help of REST APIs documentation ? I am able to generate curl requests to play with the REST APIs but not sure how it could be achieved with Python.

Any help or suggestions are most welcome.

My gitlab-ci.yml file looks like this till now as I am not able to think much after this point:

variables:
  GROUPID: 6
stages:
  - cleanup

cleanup-code-job:
  stage: cleanup
  tags:
    - build
  script:
    - echo "$GROUPID"
    ##Below curl command can be used to identify projects in group
    - curl -s --location --request GET --header 'PRIVATE-TOKEN:<PRIVATE_TOKEN>' '$CI_API_V4_URL/groups/'$GROUPID'/projects'  | sed 's/,/\n/g' | grep -w "id" | awk -F ':' '{print $2}' | sed -s 's/{"id"//g' > projects.txt
    - cat projects.txt

Thanks

CodePudding user response:

With the python-gitlab library, a python script makes this task a lot simpler to script, especially when it comes to pagination.

Additionally, you can use the Group merge requests API as a shortcut instead of listing all projects in the group then listing all merge requests in each project.

With a Python script, it might look something like this:

import gitlab
from gitlab.v4.objects import GroupMergeRequest
TOKEN = "your API key"
GITLAB_HOST = 'https://gitlab.com' # or your instance
gl = gitlab.Gitlab(GITLAB_HOST, private_token=TOKEN)

GROUP_ID = 123

def mr_meets_merge_criteria(mr: GroupMergeRequest) -> bool:
    """
    A function to check if it meets criteria to
    be merged automatically by this script
    """
    print(mr.project_id)
    print(mr.merge_status)  # e.g. 'can_be_merged'
    # check something
    ...
    return True | False

group = gl.groups.get(GROUP_ID)

# loop over all merge requests in the group
for mr in group.mergerequests.list(as_list=False):
    if mr_meets_merge_criteria(mr):
        project = gl.projects.get(mr.project_id, lazy=True)
        project_mr = project.mergerequests.get(mr.iid)
        project_mr.merge()

So, if you input the correct constants and complete the implementation of the mr_meets_merge_criteria function, that should be all that is needed :-)

  • Related