Skip to content
Snippets Groups Projects
Commit 26df0863 authored by Tim Jaacks's avatar Tim Jaacks
Browse files

Add support for retriggering merge request pipelines

* Add retrigger_mr_pipeline_py script
* Move get_merge_request() function to separate file and make it return all
  available pipelines instead of just one
* Add helper script for parsing projects from manifest file
parent 2b90ef49
No related branches found
No related tags found
1 merge request!2Add support for retriggering merge request pipelines
Pipeline #8042 passed with stage
in 1 minute and 28 seconds
...@@ -52,34 +52,6 @@ def get_latest_commit(gitlab, project, branch_name): ...@@ -52,34 +52,6 @@ def get_latest_commit(gitlab, project, branch_name):
return branch.commit return branch.commit
def get_merge_request(
gitlab, project, state, source_branch=None, target_branch=None, commit=None
):
"""Get merge request by source and target branch and optionally commit sha"""
merge_request = None
with gitlab:
try:
merge_requests = project.mergerequests.list(
source_branch=source_branch,
target_branch=target_branch,
state=state,
all=True,
retry_transient_errors=True,
)
except GitlabGetError as e:
sys.exit(
"ERROR: could not list merge requests for project '%s': %s"
% (project.name, e)
)
if commit:
for mr in merge_requests:
if mr.sha == commit:
merge_request = mr
elif merge_requests:
merge_request = merge_requests[0]
return merge_request
def rebase_merge_request(gitlab, project, merge_request): def rebase_merge_request(gitlab, project, merge_request):
"""Attempt to rebase a merge request and return the updated merge request object""" """Attempt to rebase a merge request and return the updated merge request object"""
# Rebasing takes more than one API call, see: # Rebasing takes more than one API call, see:
......
#!/usr/bin/env python3
import argparse
import sys
from lxml import etree
def main():
parser = argparse.ArgumentParser()
parser.add_argument(
"--manifest",
help="""manifest file to parse projects from""",
dest="manifest",
required=True,
)
parser.add_argument(
"--remote",
help="""get only projects with this remote""",
dest="remote",
required=False,
)
args, _ = parser.parse_known_args()
# Parse manifest file
try:
manifest = etree.parse(args.manifest)
except FileNotFoundError:
sys.exit("ERROR: file '%s' not found" % args.manifest)
# Find project references in manifest
if args.remote:
find_expression = "project[@remote='%s']" % args.remote
else:
find_expression = "project"
projects = manifest.findall(find_expression)
for project in projects:
print(project.get("name"))
if __name__ == "__main__":
main()
#!/usr/bin/env python3
import common
import argparse
import sys
from gitlab import Gitlab, GitlabGetError
def get_merge_requests(
gitlab, project, state, source_branch=None, target_branch=None, commit=None
):
"""Get merge request by source and target branch and optionally commit sha"""
merge_requests = []
with gitlab:
try:
all_merge_requests = project.mergerequests.list(
source_branch=source_branch,
target_branch=target_branch,
state=state,
all=True,
retry_transient_errors=True,
)
except GitlabGetError as e:
sys.exit(
"ERROR: could not list merge requests for project '%s': %s"
% (project.name, e)
)
if commit:
for mr in all_merge_requests:
if mr.sha == commit:
merge_requests.append(mr)
elif all_merge_requests:
merge_requests = all_merge_requests
return 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(
"--project",
help="""name of the GitLab project""",
dest="project",
required=True,
)
parser.add_argument(
"--state",
help="""state of the merge request (opened, closed, locked, or merged)""",
dest="state",
required=True,
)
parser.add_argument(
"--source-branch",
help="""source branch of the merge request""",
dest="source_branch",
required=False,
)
parser.add_argument(
"--target-branch",
help="""target branch of the merge request""",
dest="target_branch",
required=False,
)
parser.add_argument(
"--commit",
help="""commit sha of the merge request""",
dest="commit",
required=False,
)
args, _ = parser.parse_known_args()
gitlab = Gitlab(args.gitlab_url, private_token=args.token)
project = common.get_project(gitlab, args.project)
mrs = get_merge_requests(
gitlab,
project,
state=args.state,
source_branch=args.source_branch,
target_branch=args.target_branch,
commit=args.commit,
)
for mr in mrs:
print(mr.iid)
if __name__ == "__main__":
main()
...@@ -8,6 +8,7 @@ from gitlab import ( ...@@ -8,6 +8,7 @@ from gitlab import (
GitlabGetError, GitlabGetError,
) )
from accept_merge_request import accept_merge_request from accept_merge_request import accept_merge_request
from get_merge_requests import get_merge_requests
from integrate_into_manifest import integrate_into_manifest from integrate_into_manifest import integrate_into_manifest
...@@ -63,18 +64,19 @@ def main(): ...@@ -63,18 +64,19 @@ def main():
manifest_project = common.get_project(gitlab, args.manifest_project) manifest_project = common.get_project(gitlab, args.manifest_project)
# Get source merge request # Get source merge request
source_mr = common.get_merge_request( mrs = get_merge_requests(
gitlab, gitlab,
project, project,
target_branch=args.master_branch, target_branch=args.master_branch,
state="merged", state="merged",
commit=args.commit, commit=args.commit,
) )
if not source_mr: if not mrs:
sys.exit( sys.exit(
"ERROR: could not determine source merge request for commit %s" "ERROR: could not determine source merge request for commit %s"
% args.commit % args.commit
) )
source_mr = mrs[0]
# Get original branch for commit # Get original branch for commit
original_branch = source_mr.source_branch original_branch = source_mr.source_branch
...@@ -82,15 +84,15 @@ def main(): ...@@ -82,15 +84,15 @@ def main():
target_branch = args.master_branch target_branch = args.master_branch
# Check if merge request already exists # Check if merge request already exists
mr = common.get_merge_request( mrs = get_merge_requests(
gitlab, gitlab,
manifest_project, manifest_project,
source_branch=integration_branch, source_branch=integration_branch,
target_branch=target_branch, target_branch=target_branch,
state="opened", state="opened",
) )
if mr: if mrs:
sys.exit("ERROR: There is already an open merge request:\n%s" % mr.web_url) sys.exit("ERROR: There is already an open merge request:\n%s" % mrs[0].web_url)
with gitlab: with gitlab:
......
#!/usr/bin/env python3
import common
import argparse
import sys
from gitlab import Gitlab, GitlabGetError, GitlabHttpError
def retrigger_mr_pipeline(gitlab, project, mr):
with gitlab:
# Creating a merge request pipeline is not implemented in python-gitlab, so we
# have to construct the HTTP request manually.
# https://github.com/python-gitlab/python-gitlab/issues/1239
# https://docs.gitlab.com/ce/api/merge_requests.html#create-mr-pipeline
path = "%s/%s/pipelines" % (mr.manager.path, mr.iid)
try:
pipeline = gitlab.http_post(path)
except GitlabHttpError as e:
sys.exit(
"ERROR: could not create pipeline for merge request %s!%s: %s"
% (project.name, mr.iid, e)
)
print("Created new pipeline for %s :" % mr.web_url)
print(pipeline.get("web_url"))
return pipeline
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(
"--project",
help="""name of the GitLab project""",
dest="project",
required=True,
)
parser.add_argument(
"--iid",
help="""iid of the merge request""",
dest="iid",
required=True,
)
args, _ = parser.parse_known_args()
gitlab = Gitlab(args.gitlab_url, private_token=args.token)
project = common.get_project(gitlab, args.project)
try:
mr = project.mergerequests.get(args.iid)
except GitlabGetError as e:
sys.exit(
"ERROR: could not get merge request %s:!%s: %s"
% (project.name, args.iid, e)
)
if not mr:
sys.exit("ERROR: could not find merge request %s!%s" % (project.name, args.iid))
retrigger_mr_pipeline(gitlab, project, mr)
if __name__ == "__main__":
main()
#!/usr/bin/env python3
import common
import argparse
from gitlab import Gitlab
from get_merge_requests import get_merge_requests
from retrigger_mr_pipeline import retrigger_mr_pipeline
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(
"--project",
help="""name of the GitLab project""",
dest="project",
required=True,
)
parser.add_argument(
"--state",
help="""state of the merge request (opened, closed, locked, or merged)""",
dest="state",
required=True,
)
parser.add_argument(
"--source-branch",
help="""source branch of the merge request""",
dest="source_branch",
required=False,
)
parser.add_argument(
"--target-branch",
help="""target branch of the merge request""",
dest="target_branch",
required=False,
)
parser.add_argument(
"--commit",
help="""commit sha of the merge request""",
dest="commit",
required=False,
)
args, _ = parser.parse_known_args()
gitlab = Gitlab(args.gitlab_url, private_token=args.token)
project = common.get_project(gitlab, args.project)
mrs = get_merge_requests(
gitlab,
project,
state=args.state,
source_branch=args.source_branch,
target_branch=args.target_branch,
commit=args.commit,
)
for mr in mrs:
retrigger_mr_pipeline(gitlab, project, mr)
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