def release_list(definition_id=None, source_branch=None, team_instance=None, project=None, detect=None, top=None, status=None): """List release results. :param definition_id: ID of definition to list releases for. :type definition_id: int :param branch: Filter by releases for this branch. :type branch: str :param team_instance: VSTS account or TFS collection URL. Example: https://myaccount.visualstudio.com :type team_instance: str :param project: Name or ID of the team project. :type project: str :param detect: Automatically detect instance and project. Default is "on". :type detect: str :param top: Maximum number of releases to list. Default is 50. :type top: int :param status: Limit to releases with this status. :type status: str :param source_branch: Filter releases for this branch. :type source_branch: str :rtype: :class:`<Release> <release.v4_0.models.Release>` """ team_instance, project = resolve_instance_and_project(detect=detect, team_instance=team_instance, project=project) client = get_release_client(team_instance) releases = client.get_releases(definition_id=definition_id, project=project, source_branch_filter=source_branch, top=top, status_filter=status) return releases
def create_repo(name, team_instance=None, project=None, detect=None, open_browser=False): """Create a Git repository in a team project. :param name: Name for the new repository. :type name: int :param team_instance: VSTS account or TFS collection URL. Example: https://myaccount.visualstudio.com :type team_instance: str :param project: Name or ID of the team project. :type project: str :param detect: Automatically detect instance and project. Default is "on". :type detect: str :param open_browser: Open the repository page in your web browser. :type open_browser: bool :rtype: :class:`<GitRepository> <git.v4_0.models.GitRepository>` """ team_instance, project = resolve_instance_and_project( detect=detect, team_instance=team_instance, project=project) git_client = get_git_client(team_instance) create_options = GitRepositoryCreateOptions() create_options.name = name repository = git_client.create_repository( git_repository_to_create=create_options, project=project) if open_browser: _open_repository(repository, team_instance) return repository
def build_show(build_id, open_browser=False, team_instance=None, project=None, detect=None): """Get the details of a build. :param build_id: ID of the build. :type build_id: int :param open_browser: Open the build results page in your web browser. :type open_browser: bool :param team_instance: VSTS account or TFS collection URL. Example: https://myaccount.visualstudio.com :type team_instance: str :param project: Name or ID of the team project. :type project: str :param detect: Automatically detect instance and project. Default is "on". :type detect: str :rtype: :class:`<Build> <build.v4_0.models.Build>` """ try: team_instance, project = resolve_instance_and_project( detect=detect, team_instance=team_instance, project=project) client = get_build_client(team_instance) build = client.get_build(build_id=build_id, project=project) if open_browser: _open_build(build, team_instance) return build except Exception as ex: handle_command_exception(ex)
def build_queue(definition_id=None, definition_name=None, branch=None, variables=None, open_browser=False, team_instance=None, project=None, detect=None, source_branch=None): """Request (queue) a build. :param definition_id: ID of the definition to queue. Required if --name is not supplied. :type definition_id: int :param definition_name: Name of the definition to queue. Ignored if --id is supplied. :type definition_name: str :param branch: Branch to build. Required if there is not a default branch set up on the definition. Example: "dev". :type branch: str :param variables: Space separated "name=value" pairs for the variables you would like to set. :type variables: [str] :param open_browser: Open the build results page in your web browser. :type open_browser: bool :param team_instance: VSTS account or TFS collection URL. Example: https://myaccount.visualstudio.com :type team_instance: str :param project: Name or ID of the team project. :type project: str :param detect: Automatically detect instance and project. Default is "on". :type detect: str :param source_branch: Obsolete. Use --branch instead. :type source_branch: str :rtype: :class:`<Build> <build.v4_0.models.Build>` """ if branch is None: branch = source_branch team_instance, project = resolve_instance_and_project( detect=detect, team_instance=team_instance, project=project) if definition_id is None and definition_name is None: raise ValueError( 'Either the --definition-id argument or the --definition-name argument ' + 'must be supplied for this command.') client = get_build_client(team_instance) if definition_id is None: definition_id = get_definition_id_from_name(definition_name, client, project) definition_reference = DefinitionReference(id=definition_id) build = Build(definition=definition_reference) build.source_branch = resolve_git_ref_heads(branch) if variables is not None and variables: build.parameters = {} for variable in variables: separator_pos = variable.find('=') if separator_pos >= 0: build.parameters[ variable[:separator_pos]] = variable[separator_pos + 1:] else: raise ValueError( 'The --variables argument should consist of space separated "name=value" pairs.' ) queued_build = client.queue_build(build=build, project=project) if open_browser: _open_build(queued_build, team_instance) return queued_build
def build_list(definition_ids=None, branch=None, team_instance=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 team_instance: VSTS account or TFS collection URL. Example: https://myaccount.visualstudio.com :type team_instance: str :param project: Name or ID of the team project. :type project: str :param detect: Automatically detect instance 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: team_instance, project = resolve_instance_and_project( detect=detect, team_instance=team_instance, project=project) client = get_build_client(team_instance) 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, team_instance)) return builds except Exception as ex: handle_command_exception(ex)
def release_create(definition_id=None, definition_name=None, artifact_metadata_list=None, description=None, open_browser=False, team_instance=None, project=None, detect=None): """Request (create) a release. :param definition_id: ID of the definition to create. Required if --definition-name is not supplied. :type definition_id: int :param definition_name: Name of the definition to create. Ignored if --definition-id is supplied. :type definition_name: str :param open_browser: Open the release results page in your web browser. :type open_browser: bool :param team_instance: VSTS account or TFS collection URL. Example: https://myaccount.visualstudio.com :type team_instance: str :param project: Name or ID of the team project. :type project: str :param artifact_metadata_list: Space separated "alias=version_id" pairs. :type artifact_metadata_list: [str] :param description: Description of the release. :type description: str :param detect: Automatically detect instance and project. Default is "on". :type detect: str :rtype: :class:`<ReleaseStartMetadata> <release.v4_0.models.ReleaseStartMetadata>` """ team_instance, project = resolve_instance_and_project(detect=detect, team_instance=team_instance, project=project) if definition_id is None and definition_name is None: raise ValueError('Either the --definition-id argument or the --definition-name argument ' + 'must be supplied for this command.') client = get_release_client(team_instance) if definition_id is None: definition_id = get_definition_id_from_name(definition_name, client, project) artifacts = [] if artifact_metadata_list is not None and artifact_metadata_list: for artifact_metadata in artifact_metadata_list: separator_pos = artifact_metadata.find('=') if separator_pos >= 0: instance_reference = BuildVersion(id=artifact_metadata[separator_pos + 1:]) artifact = ArtifactMetadata(alias=artifact_metadata[:separator_pos], instance_reference=instance_reference) artifacts.append(artifact) else: raise ValueError('The --artifact_meta_data_list argument should consist of space separated "alias=version_id" pairs.'+artifact_metadata) release = ReleaseStartMetadata(definition_id=definition_id, artifacts=artifacts, description=description) created_release = client.create_release(release_start_metadata=release, project=project) if open_browser: _open_release(created_release) return created_release
def list_repos(team_instance=None, project=None, detect=None): """List Git repositories of a team project. :param team_instance: VSTS account or TFS collection URL. Example: https://myaccount.visualstudio.com :type team_instance: str :param project: Name or ID of the team project. :type project: str :param detect: Automatically detect instance and project. Default is "on". :type detect: str :rtype: list of :class:`<GitRepository> <git.v4_0.models.GitRepository>` """ team_instance, project = resolve_instance_and_project( detect=detect, team_instance=team_instance, project=project) git_client = get_git_client(team_instance) repository = git_client.get_repositories(project=project) return repository
def build_queue(definition_id=None, definition_name=None, source_branch=None, open_browser=False, team_instance=None, project=None, detect=None): """Request (queue) a build. :param definition_id: ID of the definition to queue. Required if --name is not supplied. :type definition_id: int :param definition_name: Name of the definition to queue. Ignored if --id is supplied. :type definition_name: str :param source_branch: Branch to build. Example: "dev". :type source_branch: str :param open_browser: Open the build results page in your web browser. :type open_browser: bool :param team_instance: VSTS account or TFS collection URL. Example: https://myaccount.visualstudio.com :type team_instance: str :param project: Name or ID of the team project. :type project: str :param detect: Automatically detect instance and project. Default is "on". :type detect: str :rtype: :class:`<Build> <build.v4_0.models.Build>` """ try: team_instance, project = resolve_instance_and_project( detect=detect, team_instance=team_instance, project=project) if definition_id is None and definition_name is None: raise ValueError( 'Either the --definition-id argument or the --definition-name argument ' + 'must be supplied for this command.') client = get_build_client(team_instance) if definition_id is None: definition_id = get_definition_id_from_name( definition_name, client, project) definition_reference = DefinitionReference(id=definition_id) build = Build(definition=definition_reference) if source_branch is not None: build.source_branch = resolve_git_ref_heads(source_branch) queued_build = client.queue_build(build=build, project=project) if open_browser: _open_build(queued_build, team_instance) return queued_build except Exception as ex: handle_command_exception(ex)
def show_repo(repo_id=None, name=None, team_instance=None, project=None, detect=None, open_browser=False): """Get the details of a Git repository. :param repo_id: ID of the repository. Required if --name is not specified. :type repo_id: int :param name: Name of the repository. Ignored if --id is specified. :type name: int :param team_instance: VSTS account or TFS collection URL. Example: https://myaccount.visualstudio.com :type team_instance: str :param project: Name or ID of the team project. :type project: str :param detect: Automatically detect instance and project. Default is "on". :type detect: str :param open_browser: Open the repository page in your web browser. :type open_browser: bool :rtype: :class:`<GitRepository> <git.v4_0.models.GitRepository>` """ try: if repo_id is None and name is None: raise CLIError( 'Either the --name argument or the --id argument needs to be specified.' ) if repo_id is not None: identifier = repo_id else: identifier = name team_instance, project = resolve_instance_and_project( detect=detect, team_instance=team_instance, project=project) git_client = get_git_client(team_instance) repository = git_client.get_repository(project=project, repository_id=identifier) if open_browser: _open_repository(repository, team_instance) return repository except Exception as ex: handle_command_exception(ex)
def build_definition_show(definition_id=None, name=None, open_browser=False, team_instance=None, project=None, detect=None): """Get the details of a build definition. :param definition_id: ID of the definition. :type definition_id: int :param name: Name of the definition. Ignored if --id is supplied. :type name: str :param open_browser: Open the definition summary page in your web browser. :type open_browser: bool :param team_instance: VSTS account or TFS collection URL. Example: https://myaccount.visualstudio.com :type team_instance: str :param project: Name or ID of the team project. :type project: str :param detect: Automatically detect values for instance and project. Default is "on". :type detect: str :rtype: BuildDefinitionReference """ try: team_instance, project = resolve_instance_and_project( detect=detect, team_instance=team_instance, project=project) client = get_build_client(team_instance) if definition_id is None: if name is not None: definition_id = get_definition_id_from_name( name, client, project) else: raise ValueError( "Either the --id argument or the --name argument must be supplied for this command." ) build_definition = client.get_definition(definition_id=definition_id, project=project) if open_browser: _open_definition(build_definition, team_instance) return build_definition except Exception as ex: handle_command_exception(ex)
def release_show(release_id, open_browser=False, team_instance=None, project=None, detect=None): """Get the details of a release. :param release_id: ID of the release. :type release_id: int :param open_browser: Open the release results page in your web browser. :type open_browser: bool :param team_instance: VSTS account or TFS collection URL. Example: https://myaccount.visualstudio.com :type team_instance: str :param project: Name or ID of the team project. :type project: str :param detect: Automatically detect instance and project. Default is "on". :type detect: str :rtype: :class:`<Release> <release.v4_0.models.Release>` """ team_instance, project = resolve_instance_and_project(detect=detect, team_instance=team_instance, project=project) client = get_release_client(team_instance) release = client.get_release(release_id=release_id, project=project) if open_browser: _open_release(release) return release
def release_definition_list(name=None, top=None, team_instance=None, project=None, artifact_type=None, artifact_source_id=None, detect=None): """List release definitions. :param name: Limit results to definitions with this name or contains this name. Example: "FabCI" :type name: str :param top: Maximum number of definitions to list. :type top: int :param team_instance: VSTS account or TFS collection URL. Example: https://myaccount.visualstudio.com :type team_instance: str :param project: Name or ID of the team project. :type project: str :param artifact_type: Release definitions with given artifactType will be returned. :type artifact_type: str :param artifact_source_id: Limit results to definitions associated with this artifact_source_id.e.g. For build it would be {projectGuid}:{BuildDefinitionId}, for Jenkins it would be {JenkinsConnectionId}:{JenkinsDefinitionId}, for TfsOnPrem it would be {TfsOnPremConnectionId}:{ProjectName}:{TfsOnPremDefinitionId}. For third-party artifacts e.g. TeamCity, BitBucket you may refer 'uniqueSourceIdentifier' inside vss-extension.json at https://github.com/Microsoft/vsts-rm-extensions/blob/master/Extensions. :type artifact_source_id: str :param detect: Automatically detect values for instance and project. Default is "on". :type detect: str :rtype: [ReleaseDefinitionReference] """ team_instance, project = resolve_instance_and_project( detect=detect, team_instance=team_instance, project=project) client = get_release_client(team_instance) query_order = 'nameAscending' definition_references = client.get_release_definitions( project=project, search_text=name, artifact_source_id=artifact_source_id, artifact_type=artifact_type, top=top, query_order=query_order) return definition_references
def query_work_items(wiql=None, query_id=None, path=None, team_instance=None, project=None, detect=None): """Query for a list of work items. :param wiql: The query in Work Item Query Language format. Ignored if --id or --path is specified. :type wiql: str :param query_id: The UUID of an existing query. Required unless --path or --wiql are specified. :type query_id: str :param path: The path of an existing query. Ignored if --id is specified. :type path: str :param team_instance: The URI for the VSTS account (https://<account>.visualstudio.com) or your TFS project collection. :type team_instance: str :param project: Name or ID of the team project. :type project: str :param detect: When 'On' unsupplied arg values will be detected from the current working directory's repo. :type detect: str :rtype: :class:`<WorkItem> <work-item-tracking.v4_0.models.WorkItem>` """ if wiql is None and path is None and query_id is None: raise CLIError( "Either the --wiql, --id, or --path argument must be specified.") team_instance, project = resolve_instance_and_project( detect=detect, team_instance=team_instance, project=project, project_required=False) client = get_work_item_tracking_client(team_instance) if query_id is None and path is not None: if project is None: raise CLIError( "The --project argument must be specified for this query.") query = client.get_query(project=project, query=path) query_id = query.id if query_id is not None: query_result = client.query_by_id(id=query_id) else: wiql_object = Wiql() wiql_object.query = wiql query_result = client.query_by_wiql(wiql=wiql_object) if query_result.work_items: _last_query_result[ _LAST_QUERY_RESULT_KEY] = query_result # store query result for table view safety_buffer = 100 # a buffer in the max url length to protect going over the limit remaining_url_length = 2048 - safety_buffer remaining_url_length -= len(team_instance) # following subtracts relative url, the asof parameter and beginning of id and field parameters. # asof value length will vary, but this should be the longest possible remaining_url_length -=\ len('/_apis/wit/workItems?ids=&fields=&asOf=2017-11-07T17%3A05%3A34.06699999999999999Z') fields = [] fields_length_in_url = 0 if query_result.columns: for field_ref in query_result.columns: fields.append(field_ref.reference_name) if fields_length_in_url > 0: fields_length_in_url += 3 # add 3 for %2C delimiter fields_length_in_url += len(uri_quote( field_ref.reference_name)) if fields_length_in_url > 800: logger.info( "Not retrieving all fields due to max url length.") break remaining_url_length -= fields_length_in_url max_work_items = 1000 work_items_batch_size = 200 current_batch = [] work_items = [] work_item_url_length = 0 for work_item_ref in query_result.work_items: if len(work_items) >= max_work_items: logger.info("Only retrieving the first %s work items.", max_work_items) break if work_item_url_length > 0: work_item_url_length += 3 # add 3 for %2C delimiter work_item_url_length += len(str(work_item_ref.id)) current_batch.append(work_item_ref.id) if remaining_url_length - work_item_url_length <= 0 or len( current_batch) == work_items_batch_size: # url is near max length, go ahead and send first request for details. # url can go over by an id length because we have a safety buffer current_batched_items = client.get_work_items( ids=current_batch, as_of=query_result.as_of, fields=fields) for work_item in current_batched_items: work_items.append(work_item) current_batch = [] work_item_url_length = 0 if current_batch: current_batched_items = client.get_work_items( ids=current_batch, as_of=query_result.as_of, fields=fields) for work_item in current_batched_items: work_items.append(work_item) # put items in the same order they appeared in the initial query results work_items = sorted(work_items, key=_get_sort_key_from_last_query_results) return work_items
def create_work_item(work_item_type, title, description=None, assigned_to=None, state=None, area=None, iteration=None, reason=None, discussion=None, fields=None, open_browser=False, team_instance=None, project=None, detect=None): """Create a work item. :param work_item_type: Name of the work item type (e.g. Bug). :type work_item_type: str :param title: Title of the work item. :type title: str :param description: Description of the work item. :type description: str :param assigned_to: Name of the person the work item is assigned-to (e.g. fabrikam). :type assigned_to: str :param state: State of the work item (e.g. active) :type state: str :param area: Area the work item is assigned to (e.g. Demos) :type area: str :param iteration: Iteration path of the work item (e.g. Demos\Iteration 1). :type iteration: str :param reason: Reason for the state work item. :type reason: str :param discussion: Comment to add to a discussion in a work item. :type discussion: str :param fields: Space separated "field=value" pairs for custom fields you would like to set. :type fields: [str] :param open_browser: Open the work item in the default web browser. :type open_browser: bool :param team_instance: The URI for the VSTS account (https://<account>.visualstudio.com) or your TFS project collection. :type team_instance: str :param project: Name or ID of the team project. :type project: str :param detect: When 'On' unsupplied arg values will be detected from the current working directory's repo. :type detect: str :rtype: :class:`<WorkItem> <work-item-tracking.v4_0.models.WorkItem>` """ try: team_instance, project = resolve_instance_and_project( detect=detect, team_instance=team_instance, project=project, project_required=True) patch_document = [] if title is not None: patch_document.append( _create_work_item_field_patch_operation( 'add', 'System.Title', title)) else: raise ValueError('--title is a required argument.') if description is not None: patch_document.append( _create_work_item_field_patch_operation( 'add', 'System.Description', description)) if assigned_to is not None: # 'assigned to' does not take an identity id. Display name works. if assigned_to == '': resolved_assigned_to = '' else: resolved_assigned_to = _resolve_identity_as_unique_user_id( assigned_to, team_instance) if resolved_assigned_to is not None: patch_document.append( _create_work_item_field_patch_operation( 'add', 'System.AssignedTo', resolved_assigned_to)) if state is not None: patch_document.append( _create_work_item_field_patch_operation( 'add', 'System.State', state)) if area is not None: patch_document.append( _create_work_item_field_patch_operation( 'add', 'System.AreaPath', area)) if iteration is not None: patch_document.append( _create_work_item_field_patch_operation( 'add', 'System.IterationPath', iteration)) if reason is not None: patch_document.append( _create_work_item_field_patch_operation( 'add', 'System.Reason', reason)) if discussion is not None: patch_document.append( _create_work_item_field_patch_operation( 'add', 'System.History', discussion)) if fields is not None and fields: for field in fields: kvp = field.split('=', 1) if len(kvp) == 2: patch_document.append( _create_work_item_field_patch_operation( 'add', kvp[0], kvp[1])) else: raise ValueError( 'The --fields argument should consist of space separated "field=value" pairs.' ) client = get_work_item_tracking_client(team_instance) work_item = client.create_work_item(document=patch_document, project=project, type=work_item_type) if open_browser: _open_work_item(work_item, team_instance) return work_item except VstsServiceError as ex: _handle_vsts_service_error(ex)