in azure-devops/azext_devops/dev/repos/pull_request.py [0:0]
def create_pull_request(project=None, repository=None, source_branch=None, target_branch=None,
title=None, description=None, auto_complete=False, squash=False,
delete_source_branch=False, bypass_policy=False, bypass_policy_reason=None,
merge_commit_message=None, optional_reviewers=None, required_reviewers=None,
work_items=None, draft=None, open=False, organization=None, detect=None,
transition_work_items=False, labels=None): # pylint: disable=redefined-builtin
"""Create a pull request.
:param project: Name or ID of the team project.
:type project: str
:param repository: Name or ID of the repository to create the pull request in.
:type repository: str
:param source_branch: Name of the source branch. Example: "dev".
:type source_branch: str
:param target_branch: Name of the target branch. If not specified, defaults to the
default branch of the target repository.
:type target_branch: str
:param title: Title for the new pull request.
:type title: str
:param draft: Use this flag to create the pull request in draft/work in progress mode.
:type draft: bool
:param description: Description for the new pull request. Can include markdown.
Each value sent to this arg will be a new line.
For example: --description "First Line" "Second Line"
:type description: list of str
:param auto_complete: Set the pull request to complete automatically when all policies have passed and
the source branch can be merged into the target branch.
:type auto_complete: bool
:param squash: Squash the commits in the source branch when merging into the target branch.
:type squash: bool
:param delete_source_branch: Delete the source branch after the pull request has been completed
and merged into the target branch.
:type delete_source_branch: bool
:param bypass_policy: Bypass required policies (if any) and completes the pull request once it
can be merged.
:type bypass_policy: bool
:param bypass_policy_reason: Reason for bypassing the required policies.
:type bypass_policy_reason: str
:param merge_commit_message: Message displayed when commits are merged.
:type merge_commit_message: str
:param optional_reviewers: Additional users or groups to include as optional reviewers on the new pull request.
Space separated.
:type optional_reviewers: list of str
:param required_reviewers: Additional users or groups to include as required reviewers on the new pull request.
Space separated.
:type required_reviewers: list of str
:param work_items: IDs of the work items to link to the new pull request. Space separated.
:type work_items: list of str
:param open: Open the pull request in your web browser.
:type open: bool
:param transition_work_items: Transition any work items linked to the pull request into the next logical state.
(e.g. Active -> Resolved)
:type transition_work_items: bool
:param labels: The labels associated with the pull request. Space separated.
:type labels: list of str
:rtype: :class:`GitPullRequest <v5_0.git.models.GitPullRequest>`
"""
organization, project, repository = resolve_instance_project_and_repo(
detect=detect,
organization=organization,
project=project,
repo=repository)
source_branch, target_branch = _get_branches_for_pull_request(
organization, project, repository, source_branch, target_branch, detect)
client = get_git_client(organization)
multi_line_description = None
if description is not None:
multi_line_description = '\n'.join(description)
if labels is not None:
labels = [WebApiTagDefinition(name=label) for label in labels.split(' ')]
pr = GitPullRequest(description=multi_line_description,
source_ref_name=source_branch,
target_ref_name=target_branch,
labels=labels)
if draft is not None:
pr.is_draft = draft
pr.title = 'Merge ' + source_branch + ' to ' + target_branch
if title is not None:
pr.title = title
pr.source_ref_name = resolve_git_ref_heads(source_branch)
pr.target_ref_name = resolve_git_ref_heads(target_branch)
if pr.source_ref_name == pr.target_ref_name:
raise CLIError('The source branch, "{}", can not be the same as the target branch.'.format
(pr.source_ref_name))
if optional_reviewers is not None:
optional_reviewers = list(set(x.lower() for x in optional_reviewers))
if required_reviewers is not None:
required_reviewers = list(set(x.lower() for x in required_reviewers))
reviewers = _resolve_reviewers_as_refs(optional_reviewers, required_reviewers, organization)
pr.reviewers = reviewers
if work_items is not None and work_items:
resolved_work_items = []
for work_item in work_items:
resolved_work_items.append(ResourceRef(id=work_item))
pr.work_item_refs = resolved_work_items
pr = client.create_pull_request(git_pull_request_to_create=pr, project=project,
repository_id=repository)
# if title or description are not provided and there is a single commit, we will
# use the its comment to populate the not-provided field(s).
# the first line of the commit comment is used for title and all lines of the
# comment are used for description.
title_from_commit = None
description_from_commit = None
if (title is None) or (description is None):
commits = client.get_pull_request_commits(repository_id=repository, pull_request_id=pr.pull_request_id,
project=project)
if len(commits) == 1:
commit_details = client.get_commit(commit_id=commits[0].commit_id, repository_id=repository,
project=project, change_count=0)
first_commit_comment = commit_details.comment
if first_commit_comment:
# when title is not specified, use the first line of first commit comment as PR title
if title is None:
title_from_commit = first_commit_comment.split("\n")[0]
# when description is not specified, use the entire commit comment as PR description
if description is None:
description_from_commit = first_commit_comment
set_completion_options = (bypass_policy or
bypass_policy_reason is not None or
squash or
merge_commit_message is not None or
delete_source_branch or
transition_work_items)
if auto_complete or set_completion_options or title_from_commit is not None or description_from_commit is not None:
pr_for_update = GitPullRequest()
if auto_complete:
# auto-complete will not get set on create, so a subsequent update is required.
pr_for_update.auto_complete_set_by = IdentityRef(id=resolve_identity_as_id(ME, organization))
if set_completion_options:
completion_options = GitPullRequestCompletionOptions()
completion_options.bypass_policy = bypass_policy
completion_options.bypass_reason = bypass_policy_reason
completion_options.delete_source_branch = delete_source_branch
completion_options.squash_merge = squash
completion_options.merge_commit_message = merge_commit_message
completion_options.transition_work_items = transition_work_items
pr_for_update.completion_options = completion_options
if title_from_commit is not None:
pr_for_update.title = title_from_commit
if description_from_commit is not None:
pr_for_update.description = description_from_commit
pr = client.update_pull_request(git_pull_request_to_update=pr_for_update,
project=pr.repository.project.id,
repository_id=pr.repository.id,
pull_request_id=pr.pull_request_id)
if open:
_open_pull_request(pr, organization)
return pr