Пример #1
0
def list_pull_requests(repository=None,
                       creator=None,
                       include_links=False,
                       reviewer=None,
                       source_branch=None,
                       status=None,
                       target_branch=None,
                       project=None,
                       skip=None,
                       top=None,
                       organization=None,
                       detect=None):
    """List pull requests.
    :param repository: Name or ID of the repository.
    :type repository: str
    :param creator: Limit results to pull requests created by this user.
    :type creator: str
    :param include_links: Include _links for each pull request.
    :type include_links: bool
    :param reviewer: Limit results to pull requests where this user is a reviewer.
    :type reviewer: str
    :param source_branch: Limit results to pull requests that originate from this source branch.
    :type source_branch: str
    :param status: Limit results to pull requests with this status.
    :type status: str
    :param target_branch: Limit results to pull requests that target this branch.
    :type target_branch: str
    :param skip: Number of pull requests to skip.
    :type skip: int
    :param top: Maximum number of pull requests to list.
    :type top: int
    :rtype: list of :class:`VssJsonCollectionWrapper <v5_0.git.models.VssJsonCollectionWrapper>`
    """
    organization, project, repository = resolve_instance_project_and_repo(
        detect=detect,
        organization=organization,
        project=project,
        repo=repository)
    search_criteria = GitPullRequestSearchCriteria(
        creator_id=resolve_identity_as_id(creator, organization),
        include_links=include_links,
        reviewer_id=resolve_identity_as_id(reviewer, organization),
        source_ref_name=resolve_git_ref_heads(source_branch),
        status=status,
        target_ref_name=resolve_git_ref_heads(target_branch))
    client = get_git_client(organization)
    if repository is None:
        pr_list = client.get_pull_requests_by_project(
            project=project,
            search_criteria=search_criteria,
            skip=skip,
            top=top)
    else:
        pr_list = client.get_pull_requests(project=project,
                                           repository_id=repository,
                                           search_criteria=search_criteria,
                                           skip=skip,
                                           top=top)
    return pr_list
def list_memberships(id, relationship='members', organization=None, detect=None):  # pylint: disable=redefined-builtin
    """List memberships for a group or user.
    :param id: Group descriptor or User Email whose membership details are required.
    :type id: str
    :rtype: [GraphMembership]
    """
    organization = resolve_instance(detect=detect, organization=organization)
    subject_descriptor = id
    client = get_graph_client(organization)
    if '@' in id or '.' not in id:
        id = resolve_identity_as_id(id, organization)
        subject_descriptor = get_descriptor_from_storage_key(id, client)
    direction = 'down'
    if relationship == 'memberof':
        direction = 'up'
    membership_list = client.list_memberships(subject_descriptor=subject_descriptor, direction=direction)
    lookup_keys = []
    for members in membership_list:
        if relationship == 'memberof':
            key = GraphSubjectLookupKey(members.container_descriptor)
        else:
            key = GraphSubjectLookupKey(members.member_descriptor)
        lookup_keys.append(key)
    subject_lookup = GraphSubjectLookup(lookup_keys=lookup_keys)
    members_details = client.lookup_subjects(subject_lookup=subject_lookup)
    return members_details
def update_user_entitlement(user,
                            license_type,
                            organization=None,
                            detect=None):
    """Update license type for a user.
    :param user: Email ID or ID of the user.
    :type user: str
    :param license_type: License type for the user.
    :type license_type: str
    :rtype: UserEntitlementsPatchResponse
    """
    patch_document = []
    value = {}
    value['accountLicenseType'] = license_type
    patch_document.append(
        _create_patch_operation('replace', '/accessLevel', value))
    organization = resolve_instance(detect=detect, organization=organization)
    if '@' in user:
        user = resolve_identity_as_id(user, organization)
    client = get_member_entitlement_management_client(organization)
    user_entitlement_update = client.update_user_entitlement(
        document=patch_document, user_id=user)
    if user_entitlement_update.is_success is False and \
            user_entitlement_update.operation_results[0].errors[0] is not None:
        raise CLIError(
            user_entitlement_update.operation_results[0].errors[0]['value'])
    return user_entitlement_update.user_entitlement
Пример #4
0
def add_membership(member_id, group_id, organization=None, detect=None):
    """Add membership.
    :param member_id: Descriptor of the group or Email Id of the user to be added.
    User should already be a part of the organization. Use `az devops user add` command to add an user to organization.
    :type member_id: str
    :param group_id: Descriptor of the group to which member needs to be added.
    :type group_id: str
    :rtype: :class:`<GraphMembership> <azure.devops.v5_0.graph.models.GraphMembership>`
    """
    organization = resolve_instance(detect=detect, organization=organization)
    client = get_graph_client(organization)
    subject_descriptor = member_id
    if '@' in member_id or '.' not in member_id:
        member_id = resolve_identity_as_id(member_id, organization)
        subject_descriptor = get_descriptor_from_storage_key(member_id, client)
    membership_details = client.add_membership(
        subject_descriptor=subject_descriptor, container_descriptor=group_id)
    lookup_keys = []
    container = GraphSubjectLookupKey(membership_details.container_descriptor)
    subject = GraphSubjectLookupKey(membership_details.member_descriptor)
    lookup_keys.append(container)
    lookup_keys.append(subject)
    subject_lookup = GraphSubjectLookup(lookup_keys=lookup_keys)
    membership_details = client.lookup_subjects(subject_lookup=subject_lookup)
    return membership_details
def build_list(definition_ids=None,
               branch=None,
               organization=None,
               project=None,
               detect=None,
               top=None,
               result=None,
               status=None,
               reason=None,
               tags=None,
               requested_for=None):
    """List build results.
    :param definition_ids: IDs (space separated) of definitions to list builds for.
    :type definition_ids: list of int
    :param branch: Filter by builds for this branch.
    :type branch: str
    :param organization: Azure Devops organization URL. Example: https://dev.azure.com/MyOrganizationName/
    :type organization: str
    :param project: Name or ID of the team project.
    :type project: str
    :param detect: Automatically detect organization and project. Default is "on".
    :type detect: str
    :param top: Maximum number of builds to list.
    :type top: int
    :param result: Limit to builds with this result.
    :type result: str
    :param status: Limit to builds with this status.
    :type status: str
    :param reason: Limit to builds with this reason.
    :type reason: str
    :param tags: Limit to builds with each of the specified tags. Space separated.
    :type tags: list of str
    :param requested_for: Limit to builds requested for this user or group.
    :type requested_for: str
    :rtype: :class:`<Build> <build.v4_0.models.Build>`
    """
    try:
        organization, project = resolve_instance_and_project(
            detect=detect, organization=organization, project=project)
        client = get_build_client(organization)
        if definition_ids is not None and definition_ids:
            definition_ids = list(set(definition_ids))  # make distinct
        if tags is not None and tags:
            tags = list(set(tags))  # make distinct
        builds = client.get_builds(definitions=definition_ids,
                                   project=project,
                                   branch_name=resolve_git_ref_heads(branch),
                                   top=top,
                                   result_filter=result,
                                   status_filter=status,
                                   reason_filter=reason,
                                   tag_filters=tags,
                                   requested_for=resolve_identity_as_id(
                                       requested_for, organization))
        return builds
    except VstsServiceError as ex:
        raise CLIError(ex)
Пример #6
0
def _resolve_reviewers_as_ids(reviewers, organization):
    """Takes a list containing identity names, emails, and ids,
    and returns a list of IdentityRefWithVote objects.
    """
    resolved_reviewers = None
    if reviewers is not None and reviewers:
        resolved_reviewers = []
        for reviewer in reviewers:
            resolved_reviewers.append(resolve_identity_as_id(reviewer, organization))
    return resolved_reviewers
def delete_user_entitlement(user, organization=None, detect=None):
    """Remove user from an organization.
    :param user: Email ID or ID of the user.
    :type user: str
    """
    organization = resolve_instance(detect=detect, organization=organization)
    if '@' in user:
        user = resolve_identity_as_id(user, organization)
    client = get_member_entitlement_management_client(organization)
    delete_user_entitlement_details = client.delete_user_entitlement(user_id=user)
    return delete_user_entitlement_details
Пример #8
0
def _resolve_reviewers_as_refs(reviewers, organization):
    """Takes a list containing identity names, emails, and ids,
    and return a list of IdentityRefWithVote objects.
    :rtype: list of :class:`IdentityRefWithVote <v5_0.git.models.IdentityRefWithVote>`
    """
    resolved_reviewers = None
    if reviewers is not None and reviewers:
        resolved_reviewers = []
        for reviewer in reviewers:
            resolved_reviewers.append(IdentityRefWithVote(id=resolve_identity_as_id(reviewer, organization)))
    return resolved_reviewers
def get_user_entitlement(user, organization=None, detect=None):
    """Show user details.
    :param user: Email ID or ID of the user.
    :type user: str
    :rtype: UserEntitlement
    """
    organization = resolve_instance(detect=detect, organization=organization)
    if '@' in user:
        user = resolve_identity_as_id(user, organization)
    client = get_member_entitlement_management_client(organization)
    user_entitlement_details = client.get_user_entitlement(user_id=user)
    return user_entitlement_details
def pipeline_run_list(pipeline_ids=None,
                      branch=None,
                      organization=None,
                      project=None,
                      detect=None,
                      top=None,
                      query_order=None,
                      result=None,
                      status=None,
                      reason=None,
                      tags=None,
                      requested_for=None):
    """ List the pipeline runs in a project.
    :param pipeline_ids: IDs (space separated) of definitions to list builds for.
    For multiple pipeline ids:  --pipeline-ids 1 2
    :type pipeline_ids: list of int
    :param branch: Filter by builds for this branch.
    :type branch: str
    :param top: Maximum number of builds to list.
    :type top: int
    :param query_order: Order of pipeline runs.
    :type query_order: str
    :param result: Limit to builds with this result.
    :type result: str
    :param status: Limit to builds with this status.
    :type status: str
    :param reason: Limit to builds with this reason.
    :type reason: str
    :param tags: Limit to builds with each of the specified tags. Space separated.
    :type tags: list of str
    :param requested_for: Limit to builds requested for this user or group.
    :type requested_for: str
    """
    organization, project = resolve_instance_and_project(
        detect=detect, organization=organization, project=project)
    client = get_build_client(organization)
    if pipeline_ids is not None and pipeline_ids:
        pipeline_ids = list(set(pipeline_ids))  # make distinct
    if tags is not None and tags:
        tags = list(set(tags))  # make distinct
    query_order = _resolve_runs_query_order(query_order)
    builds = client.get_builds(definitions=pipeline_ids,
                               project=project,
                               branch_name=resolve_git_ref_heads(branch),
                               top=top,
                               result_filter=result,
                               status_filter=status,
                               reason_filter=reason,
                               tag_filters=tags,
                               query_order=query_order,
                               requested_for=resolve_identity_as_id(
                                   requested_for, organization))
    return builds
def resolveIdentityMailsToIds(mailList, organization):
    logger.debug('mail list %s ', mailList)
    if not mailList or (not mailList.strip()):
        return None

    idList = []
    for mail in mailList.split(';'):
        mailStripped = mail.strip()
        logger.debug('trying to resolve %s', mailStripped)
        identityId = resolve_identity_as_id(mailStripped, organization)
        logger.debug('got id as %s', identityId)
        idList.append(identityId)

    return idList
Пример #12
0
def build_list(definition_ids=None,
               branch=None,
               organization=None,
               project=None,
               detect=None,
               top=None,
               result=None,
               status=None,
               reason=None,
               tags=None,
               requested_for=None):
    """List build results.
    :param definition_ids: IDs (space separated) of definitions to list builds for.
    :type definition_ids: list of int
    :param branch: Filter by builds for this branch.
    :type branch: str
    :param top: Maximum number of builds to list.
    :type top: int
    :param result: Limit to builds with this result.
    :type result: str
    :param status: Limit to builds with this status.
    :type status: str
    :param reason: Limit to builds with this reason.
    :type reason: str
    :param tags: Limit to builds with each of the specified tags. Space separated.
    :type tags: list of str
    :param requested_for: Limit to builds requested for this user or group.
    :type requested_for: str
    :rtype: :class:`<Build> <build.v4_0.models.Build>`
    """
    organization, project = resolve_instance_and_project(
        detect=detect, organization=organization, project=project)
    client = get_build_client(organization)
    if definition_ids is not None and definition_ids:
        definition_ids = list(set(definition_ids))  # make distinct
    if tags is not None and tags:
        tags = list(set(tags))  # make distinct
    builds = client.get_builds(definitions=definition_ids,
                               project=project,
                               branch_name=resolve_git_ref_heads(branch),
                               top=top,
                               result_filter=result,
                               status_filter=status,
                               reason_filter=reason,
                               tag_filters=tags,
                               requested_for=resolve_identity_as_id(
                                   requested_for, organization))
    return builds
Пример #13
0
def vote_pull_request(id, vote, organization=None, detect=None):  # pylint: disable=redefined-builtin
    """Vote on a pull request.
    :param id: ID of the pull request.
    :type id: int
    :param vote: New vote value for the pull request.
    :type vote: int
    :rtype: :class:`IdentityRefWithVote <v5_0.git.models.IdentityRefWithVote>`
    """
    organization = resolve_instance(detect=detect, organization=organization)
    client = get_git_client(organization)
    pr = client.get_pull_request_by_id(id)
    resolved_reviewer = IdentityRefWithVote(id=resolve_identity_as_id(ME, organization))
    resolved_reviewer.vote = _convert_vote_to_int(vote)
    created_reviewer = client.create_pull_request_reviewer(project=pr.repository.project.id,
                                                           repository_id=pr.repository.id,
                                                           pull_request_id=id,
                                                           reviewer_id=resolved_reviewer.id,
                                                           reviewer=resolved_reviewer)
    return created_reviewer
def remove_membership(member_id, group_id, organization=None, detect=None):
    """Remove membership.
    :param member_id: Descriptor of the group or Email Id of the user to be removed.
    :type member_id: str
    :param group_id: Descriptor of the group from which member needs to be removed.
    :type group_id: str
    """
    organization = resolve_instance(detect=detect, organization=organization)
    client = get_graph_client(organization)
    subject_descriptor = member_id
    if '@' in member_id or '.' not in member_id:
        member_id = resolve_identity_as_id(member_id, organization)
        subject_descriptor = get_descriptor_from_storage_key(member_id, client)
    try:
        client.check_membership_existence(subject_descriptor=subject_descriptor,
                                          container_descriptor=group_id)
        membership_details = client.remove_membership(subject_descriptor=subject_descriptor,
                                                      container_descriptor=group_id)
    except AzureDevOpsClientRequestError as ex:
        logger.debug(ex, exc_info=True)
        raise CLIError("Membership doesn't exists.")
    return membership_details
Пример #15
0
def update_pull_request(
        id,
        title=None,
        description=None,
        auto_complete=None,  # pylint: disable=redefined-builtin
        squash=None,
        delete_source_branch=None,
        bypass_policy=None,
        draft=None,
        bypass_policy_reason=None,
        merge_commit_message=None,
        organization=None,
        detect=None,
        transition_work_items=None):
    """Update a pull request.
    :param id: ID of the pull request.
    :type id: int
    :param title: New title for the pull request.
    :type title: str
    :param description: New description for the 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 draft: Publish the PR or convert to draft mode.
    :type draft: bool
    :param merge_commit_message: Message displayed when commits are merged.
    :type merge_commit_message: str
    :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
    :rtype: :class:`GitPullRequest <v5_0.git.models.GitPullRequest>`
    """
    organization = resolve_instance(detect=detect, organization=organization)
    client = get_git_client(organization)
    existing_pr = client.get_pull_request_by_id(id)
    if description is not None:
        multi_line_description = '\n'.join(description)
    else:
        multi_line_description = None
    pr = GitPullRequest(title=title, description=multi_line_description)
    if (bypass_policy is not None or  # pylint: disable=too-many-boolean-expressions
            bypass_policy_reason is not None or squash is not None or
            merge_commit_message is not None or delete_source_branch
            is not None or transition_work_items is not None):
        completion_options = existing_pr.completion_options
        if completion_options is None:
            completion_options = GitPullRequestCompletionOptions()
        if bypass_policy is not None:
            completion_options.bypass_policy = bypass_policy
        if bypass_policy_reason is not None:
            completion_options.bypass_reason = bypass_policy_reason
        if delete_source_branch is not None:
            completion_options.delete_source_branch = delete_source_branch
        if squash is not None:
            completion_options.squash_merge = squash
        if merge_commit_message is not None:
            completion_options.merge_commit_message = merge_commit_message
        if transition_work_items is not None:
            completion_options.transition_work_items = transition_work_items
        pr.completion_options = completion_options
    if auto_complete is not None:
        if auto_complete:
            pr.auto_complete_set_by = IdentityRef(
                id=resolve_identity_as_id(ME, organization))
        else:
            pr.auto_complete_set_by = IdentityRef(id=EMPTY_UUID)
    if draft is not None:
        pr.is_draft = draft
    pr = client.update_pull_request(
        git_pull_request_to_update=pr,
        project=existing_pr.repository.project.name,
        repository_id=existing_pr.repository.name,
        pull_request_id=id)
    return pr
Пример #16
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,
                        reviewers=None,
                        work_items=None,
                        draft=None,
                        open=False,
                        organization=None,
                        detect=None,
                        transition_work_items=False):  # 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 reviewers: Additional users or groups to include as reviewers on the new pull request.
                      Space separated.
    :type 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
    :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)
    pr = GitPullRequest(description=multi_line_description,
                        source_ref_name=source_branch,
                        target_ref_name=target_branch)
    if draft is not None:
        pr.is_draft = draft
    if title is not None:
        pr.title = title
    else:
        pr.title = 'Merge ' + source_branch + ' to ' + target_branch
    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))
    pr.reviewers = _resolve_reviewers_as_refs(reviewers, organization)
    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)
    title_from_commit = None
    if title is None:
        # if title wasn't specified and only one commit, we will set the PR title to the comment of that commit
        commits = client.get_pull_request_commits(
            repository_id=repository,
            pull_request_id=pr.pull_request_id,
            project=project)
        if len(commits) == 1:
            title_from_commit = commits[0].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:
        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
        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