Search code examples
gitlab-api

creating/editing gitlab repository using gitlab api


I would like to write a script that edits a bunch of settings for several gitlab repositories.

for now I have worked out

    #!/bin/bash
PER_PAGE=50

function make_request {
    local page="$1"
    local url="${BASE_URL}${ENDPOINT}?private_token=${PRIVATE_TOKEN}&per_page=${PER_PAGE}&page=${page}"
    local response=$(curl -sS "$url")
    echo "$response"
}


export approvals_before_merge="2"
export merge_method="merge"
export squash_option="default_off"
export remove_source_branch_after_merge='true'
export only_allow_merge_if_pipeline_succeeds='true'
export only_allow_merge_if_all_discussions_are_resolved='true'


for ((page = 1; page <= total_pages; page++)); do
      echo page number $page
    response=$(make_request "$page")
    # echo $response
    # response=''
    if [  "$response" = "[]" ]; then
        echo "Variable is empty. Stopping the loop."
        break
    fi
    # Process the data from each page using jq here

    # Process the response to populate the array_of_arrays with the data
        while IFS=$'\n' read -r line; do
            array_of_arrays+=("$line")
        done < <(echo "$response" | jq -r '.[] | [(.id, .name)] | @tsv')
        # echo $response | jq -r '.[]| [.name,.id]'
        # Iterate over the array_of_arrays and print the two elements for each row
        for ((i = 0; i < ${#array_of_arrays[@]}; i+=1)); do
            IFS=$'\t' read -r id name <<< "${array_of_arrays[$i]}"
            echo "i: $(((i )+$project_number)), Project ID: $id, Project Name: $name"

        curl  -sS --request PUT --header "PRIVATE-TOKEN:  ${PRIVATE_TOKEN}" \
        --header "Content-Type: application/json" \
        --data '{"approvals_before_merge": "'"$approvals_before_merge"'","merge_method": "'"$merge_method"'","squash_option": "'"$squash_option"'","remove_source_branch_after_merge": "'"$remove_source_branch_after_merge"'","only_allow_merge_if_pipeline_succeeds": "'"$only_allow_merge_if_pipeline_succeeds"'","only_allow_merge_if_all_discussions_are_resolved": "'"$only_allow_merge_if_all_discussions_are_resolved"'"}' \
        "https://gitlab.com/api/v4/projects/$id"


        done
    #   project_number=$(((i )+$project_number))
done

But what I really want is to set

  • MR templates
  • new commit regex
  • code owners
  • branch regex

I know is possible using terraform but I am struggling using the api. I tried with

NEW_MERGE_TEMPLATE="
## Overview
### What is changing: 
<!-- Add a list describing the changes you have made in this MR -->

### What is the result of these changes:
<!-- Add a list describing the intended result of these changes -->

## Related ticket
 
<!-- Replace XXX with the ticket ID, e.g. 123 -->
 
- [XXX](https://jira.extge.co.uk/browse/XXX)
 
## Checklist
 
<!-- Replace [ ] with [x] for the items that apply -->
 
- [ ] The PR only includes changes relating to 1 ticket
- [ ] I have added labels to reflect change type
- [ ] I have added tests to cover my changes
- [ ] I have updated the documentation where required
- [ ] I have informed the team of any impactful changes"

# Define your new branch regex
NEW_BRANCH_REGEX="^(([A-Za-z0-9]+)-\\d+|HOTFIX|hotfix|\\d+)\\-.*"

# Define your new commit regex
NEW_COMMIT_REGEX="^(?P<type>build|chore|ci|docs|feat|fix|perf|refactor|revert|style|test|¯\\\\_(ツ)_/¯)(?P<scope>\\(\\w+\\))?(?P<breaking>!)?(?P<subject>:\\s.*)?|^(?P<merge>Merge \\w+)"

curl --request PUT --header "PRIVATE-TOKEN: $PRIVATE_TOKEN" \
     --header "Content-Type: application/json" \
     --data '{"merge_requests_template": "'"$NEW_MERGE_TEMPLATE"'"}' \
     "$BASE_URL/projects/$PROJECT_ID"

# # # Update the branch name regex
curl --request PUT --header "PRIVATE-TOKEN: $PRIVATE_TOKEN" \
     --header "Content-Type: application/json" \
     --data '{"name_regex": "'"$NEW_BRANCH_REGEX"'"}' \
     "$BASE_URL/projects/$PROJECT_ID"

# # # Update the commit message regex
curl --request PUT --header "PRIVATE-TOKEN: $PRIVATE_TOKEN" \
     --header "Content-Type: application/json" \
     --data '{"commit_message_regex": "'"$NEW_COMMIT_REGEX"'"}' \
     "$BASE_URL/projects/$PROJECT_ID"

# # # # Enable code owners with the specified user IDs
curl --request PUT --header "PRIVATE-TOKEN: $PRIVATE_TOKEN" \
     --header "Content-Type: application/json" \
     --data '{"merge_requests_access_level": "enabled", "approvals_before_merge": 2, "code_owner_approval_required": $(echo ${CODE_OWNER_IDS[@]} | jq -R '[split(" ") | .[] | tonumber]')}" \
     "$GITLAB_API/projects/$PROJECT_ID"

the fail I suspect is due to the string not been accepted.

what's a working example? for those expressions?


Solution

  • I switched to use the Gitlab Python library

    and something like this

    def update_settings(project_id,gl_client):
        try:
            # Get the project by ID
            project = gl_client.projects.get(project_id)
            
            # settings = project.mergerequests.settings.get()
    
            # Set approvals_before_merge
            project.approvals_before_merge = 2
    
            # Set merge_method to "merge"
    
            project.merge_method = "merge"
    
            project.default_branch = 'develop'
            # Set squash_option to "default_off"
            project.squash_option = "default_off"
    
            # Set remove_source_branch_after_merge to True
            project.remove_source_branch_after_merge = True
    
            project.allow_merge_on_skipped_pipeline = False
    
            # Set only_allow_merge_if_pipeline_succeeds to True
            project.only_allow_merge_if_pipeline_succeeds = True
    
            # Set only_allow_merge_if_all_discussions_are_resolved to True
            project.only_allow_merge_if_all_discussions_are_resolved = True
    
            project.merge_request_template = 'Default.md'
    
            # Save the updated settings
            project.save()
    
            p_mras = project.approvals.get()
            p_mras.approvals_before_merge = 2
            p_mras.reset_approvals_on_push = True
            p_mras.disable_overriding_approvers_per_merge_request = True
            p_mras.merge_requests_author_approval = False
            p_mras.merge_requests_disable_committers_approval = True
            p_mras.save()
    
    
            print(f"project settings updated successfully for project ID {project_id}")
        except gitlab.exceptions.GitlabGetError as e:
            print(f"Failed to update settings  for project ID {project_id}: {e}")
    

    actually updates the settings!