#!/usr/bin/env python3 import common import argparse import sys from gitlab import Gitlab, GitlabCreateError from accept_merge_request import accept_merge_request from create_merge_request import create_merge_request from get_merge_requests import get_merge_requests from update_submodule import update_submodule 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( "--submodule", help="""submodule to update""", dest="submodule", required=True, ) parser.add_argument( "--revision", help="""new revision for submodule""", dest="revision", required=True, ) parser.add_argument( "--branch", help="""project branch (if not default branch)""", dest="branch", required=False, default=None, ) parser.add_argument( "--merge", help="""if set, perform merge after integration""", dest="merge", action="store_true", required=False, default=False, ) args, _ = parser.parse_known_args() gitlab = Gitlab(args.gitlab_url, private_token=args.token) project = common.get_project(gitlab, args.project) # Update submodule integration_branch, integration_commit, submodule_project = update_submodule( project, args.submodule, args.revision, args.branch ) # Get source merge request mrs = get_merge_requests( submodule_project, target_branch="master", commit=args.revision, ) if not mrs: sys.exit( "ERROR: could not determine source merge request for commit %s" % args.revision ) source_mr = mrs[0] # Create merge request mr, created = create_merge_request( project, integration_branch, project.default_branch ) if created: common.crosslink_merge_requests(source_mr, mr) print("Created new merge request:\n%s" % mr.web_url) else: print("Existing integration merge request:\n%s" % mr.web_url) # Explicitly trigger a pipeline on the integration branch if it has not run for the # head commit yet (automatic pipelines are disabled for integration branches) if not project.pipelines.list(sha=integration_commit): try: project.pipelines.create({"ref": integration_branch}) except GitlabCreateError as e: sys.exit("ERROR: could not create merge request pipeline: %s" % e) if not args.merge: print( "Skipping automatic merge in MR context. If you like to extend the " "integration MR by hand, please do it now. Afterwards you can either merge " "it by hand or re-run this job on the master branch after the source MR " "has been merged." ) sys.exit(0) # Wait until GitLab has checked merge status common.wait_until_merge_status_is_set(project, mr) # Attempt to merge merged = accept_merge_request(project, mr, rebase=True) if not merged: sys.exit( "Integration MR could not be merged. You have two possibilities to fix " "this:\n" " 1. Checkout the MR and rebase it on the current master manually, or\n" " 2. Delete the MR (Edit -> Delete in the MR UI)\n" "In either case restart this job afterwards in order to get it merged." ) print("Successfully merged") if __name__ == "__main__": main()