Skip to content
Snippets Groups Projects
Commit c8d434ef authored by Lorenzo Pagliai's avatar Lorenzo Pagliai
Browse files

[INTEGRATION][SETUP] Insert script for branch setup

The objective of the script inserted in this commit is to:
* Automate the setup of new protected main branches by creating
them within a specific group and/or in a list of projects chosen by the user.
* Automate the configuration of the variables required to enable integration via CI/CD,
i.e. INTEGRATION variable.
* Automate the creation of a manifest branch having the same name with all
variables configured correctly.
* Automate the deletion of these branches and the cleanup of the variables
if it is no longer necessary to use the branches.

The script is not integrated within the pipeline flow but to be run
on spot when a new version of Yocto is passed to support, and/or for the creation
of new branches that require development of new functionality.
parent 12a33b1c
No related branches found
No related tags found
No related merge requests found
import gitlab
import argparse
def create_new_branch(project, start_branch, end_branch):
try:
project.branches.create({'branch': end_branch, 'ref': start_branch})
project.protectedbranches.create({'name': end_branch, 'push_access_level': gitlab.MAINTAINER_ACCESS})
print(f"Successfully created branch '{end_branch}' from '{start_branch}' in project '{project.name}'")
except gitlab.exceptions.GitlabCreateError as e:
print(f"Failed to create branch '{end_branch}' from '{start_branch}' in project '{project.name}': {e}")
except Exception as e:
print(f"An error occurred while creating branch '{end_branch}' from '{start_branch}' in project '{project.name}': {e}")
def delete_branch(project, branch_name):
try:
project.branches.delete(branch_name)
project.protectedbranches.get(branch_name).delete()
print(f"Successfully deleted branch '{branch_name}' in project '{project.name}'")
except gitlab.exceptions.GitlabCreateError as e:
print(f"Failed to delete branch '{branch_name}'' in project '{project.name}': {e}")
except Exception as e:
print(f"An error occurred while deleting branch '{branch_name}' in project '{project.name}': {e}")
def update_variable(project, variable_name, action, value):
try:
variables = project.variables.list(all=True)
for variable in variables:
if variable.key == variable_name:
if action == 'create':
variable.value += f'\n{value}'
elif action == 'delete':
variable.value = variable.value.replace(value, '')
# Remove any trailing newline characters
variable.value = variable.value.rstrip('\n')
variable.save()
print(f"Successfully updated variable '{variable_name}' in project '{project.name}'")
break
except gitlab.exceptions.GitlabUpdateError as e:
print(f"Failed to update variable '{variable_name}' in project '{project.name}': {e}")
except Exception as e:
print(f"An error occurred while updating variable '{variable_name}' in project '{project.name}': {e}")
def update_ci_variable(manifest_repo, start_branch, end_branch):
try:
# Fetch the .gitlab-ci.yml file
file = manifest_repo.files.get(file_path='.gitlab-ci.yml', ref=end_branch)
content = file.decode().decode('utf-8')
# Update the value of the MASTER_BRANCH variable
new_content = content.replace(f'MASTER_BRANCH: {start_branch}', f'MASTER_BRANCH: {end_branch}')
# Commit the changes perfomrm inside .gitlab-ci.yml
commit_data = {
'branch': end_branch,
'commit_message': f"Update MASTER_BRANCH variable in .gitlab-ci.yml to {end_branch}",
'actions': [
{
'action': 'update',
'file_path': '.gitlab-ci.yml',
'content': new_content,
'encoding': 'text'
}
]
}
manifest_repo.commits.create(commit_data)
print(f"Successfully updated .gitlab-ci.yml in {manifest_repo.name} to use {end_branch}")
except Exception as e:
print(f"Error updating .gitlab-ci.yml in {manifest_repo.name}: {str(e)}")
def main():
parser = argparse.ArgumentParser(description="GitLab Branch and CI/CD Variable Manager")
parser.add_argument(
"--url",
help="URL of the GitLab instance",
dest="gitlab_url",
required=True,
)
parser.add_argument(
"--token",
help="""GitLab REST API private access token""",
dest="access_token",
required=True,
)
parser.add_argument(
"--group",
help="Name of the GitLab group where the repo that integrates into the manifest are located",
dest="group_name",
required=True,
)
parser.add_argument(
"--other-repos",
nargs='+',
help="Name of other GitLab repositories external to the group",
dest="other_repos",
required=True,
)
parser.add_argument(
"--start-branch",
help="Name of the starting branch",
dest="start_branch",
required=True,
)
parser.add_argument(
"--end-branch",
help="Name of the ending branch",
dest="end_branch",
required=True,
)
parser.add_argument(
"--manifest-repo",
help="Name of the manifest repository",
dest="manifest_repo",
required=True,
)
parser.add_argument(
"--variable",
help="Name of the CI/CD variable to be changed",
dest="variable_name",
required=True,
)
parser.add_argument(
"--action",
help="Action to perform: 'create' or 'delete'",
dest="action",
required=True,
)
args = parser.parse_args()
gl = gitlab.Gitlab(args.gitlab_url, private_token=args.access_token)
gl.auth()
group = gl.groups.get(args.group_name)
# Iterate over projects in the group
for group_project in group.projects.list(all=True, include_subgroups=True):
project = gl.projects.get(group_project.id)
print(project.name)
## Layers projects first, then separately manifest repo
if not "manifest" in project.name:
if args.action == 'create':
# Create new branch in project
create_new_branch(project, args.start_branch, args.end_branch)
elif args.action == 'delete':
# Delete old branch in project
delete_branch(project, args.end_branch)
# Update CI/CD variable
value = f"{args.end_branch}:{args.manifest_repo}:{args.end_branch}"
update_variable(project, args.variable_name, args.action, value)
# Iterate over spot projects in other groups
for project in args.other_repos:
project_group_name, project_name = project.rsplit('/', 1)
project_group = gl.groups.get(project_group_name)
project_project_id = project_group.projects.list(search=project_name)[0]
project_repo = gl.projects.get(project_project_id.id)
print(project_repo.name)
if args.action == 'create':
# Create new branch in project
create_new_branch(project_repo, args.start_branch, args.end_branch)
elif args.action == 'delete':
# Delete old branch in project
delete_branch(project_repo, args.end_branch)
# Update CI/CD variable
value = f"{args.end_branch}:{args.manifest_repo}:{args.end_branch}"
update_variable(project_repo, args.variable_name, args.action, value)
# Performing modifications on manifest repo
manifest_group_name, manifest_name = args.manifest_repo.rsplit('/', 1)
manifest_group = gl.groups.get(manifest_group_name)
manifest_project_id = manifest_group.projects.list(search=manifest_name)[0]
manifest_project = gl.projects.get(manifest_project_id.id)
if args.action == 'create':
# Create new branch in project
create_new_branch(manifest_project, args.start_branch, args.end_branch)
# Change .gitlab-ci.yml MASTER_BRANCH reference
update_ci_variable(manifest_project, args.start_branch, args.end_branch)
elif args.action == 'delete':
# Delete old branch in project
delete_branch(manifest_project, args.end_branch)
if __name__ == "__main__":
main()
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment