Get-ADOBuild.ps1
function Get-ADOBuild { <# .Synopsis Gets Azure DevOps Builds, Definitions, and associated information. .Description Gets Azure DevOps Builds or Definitions and associated information. Gets builds by default. To get build definitions, use -Definition Given a -BuildID, we can can get associated information: |Parameter | Effect | |----------|----------------------------------------------| |-Artfiact | Get a list of all build artifacts | |-ChangeSet | Get the build's associated changeset | |-Log | Get a list of all build logs | |-LogID | Get the content of a specific LogID | |-Timeline | Gets the build timeline | |-BuildMetaData | Returns system metadata about the build | Given a -Definition ID, we can get associated information: |Parameter | Effect | |----------|--------------------------------------------------| |-Status | Gets the status of the build definition | |-Metric | Gets metrics about the build definition | |-Revision | Gets the revisions of a build definition| |-DefinitionMetadata| Gets metadata about a build definition | .Example Get-ADOBuild -Organization StartAutomating -Project PSDevOps .Example Get-ADOBuild -Organization StartAutomating -Project PSDevOps -Definition .Link https://docs.microsoft.com/en-us/rest/api/azure/devops/build/builds/get?view=azure-devops-rest-5.1 .Link https://docs.microsoft.com/en-us/rest/api/azure/devops/build/artifacts/list?view=azure-devops-rest-5.1 .Link https://docs.microsoft.com/en-us/rest/api/azure/devops/build/builds/get%20build%20logs?view=azure-devops-rest-5.1 .Link https://docs.microsoft.com/en-us/rest/api/azure/devops/build/timeline/get?view=azure-devops-rest-5.1 .Link https://docs.microsoft.com/en-us/rest/api/azure/devops/build/properties/get%20build%20properties?view=azure-devops-rest-5.1 .Link https://docs.microsoft.com/en-us/rest/api/azure/devops/build/definitions/get?view=azure-devops-rest-5.1 .Link https://docs.microsoft.com/en-us/rest/api/azure/devops/build/properties/get%20definition%20properties?view=azure-devops-rest-5.1 .Link https://docs.microsoft.com/en-us/rest/api/azure/devops/build/metrics/get%20definition%20metrics?view=azure-devops-rest-5.1 #> [CmdletBinding(DefaultParameterSetName='build/builds')] [OutputType('PSDevOps.Build','PSDevOps.Build.Definition', 'PSDevOps.Build.Timeline', 'PSDevOps.Build.Change', 'PSDevOps.Build.Report', 'PSDevOps.Build.Artifact', 'PSDevOps.Build.CodeCoverage')] param( # The Organization [Parameter(Mandatory,ValueFromPipelineByPropertyName)] [Alias('Org')] [string] $Organization, # The Project [Parameter(Mandatory,ValueFromPipelineByPropertyName)] [string] $Project, # The server. By default https://feeds.dev.azure.com/. [Parameter(ValueFromPipelineByPropertyName)] [uri] $Server = "https://dev.azure.com/", # The api version. By default, 5.1-preview. [string] $ApiVersion = "5.1-preview", # Build ID [Parameter(Mandatory,ParameterSetName='build/builds/{buildId}',ValueFromPipelineByPropertyName)] [Parameter(Mandatory,ParameterSetName='build/builds/{buildId}/properties',ValueFromPipelineByPropertyName)] [Parameter(Mandatory,ParameterSetName='build/builds/{buildId}/logs',ValueFromPipelineByPropertyName)] [Parameter(Mandatory,ParameterSetName='build/builds/{buildId}/logs/{logId}',ValueFromPipelineByPropertyName)] [Parameter(Mandatory,ParameterSetName='build/builds/{buildId}/changes',ValueFromPipelineByPropertyName)] [Parameter(Mandatory,ParameterSetName='build/builds/{buildId}/artifacts',ValueFromPipelineByPropertyName)] [Parameter(Mandatory,ParameterSetName='build/builds/{buildId}/timeline',ValueFromPipelineByPropertyName)] [Parameter(Mandatory,ParameterSetName='build/builds/{buildId}/report',ValueFromPipelineByPropertyName)] [Parameter(Mandatory,ParameterSetName='test/codeCoverage',ValueFromPipelineByPropertyName)] [string] $BuildID, # If set [Parameter(ParameterSetName='build/builds/{buildId}')] [Alias('Details')] [switch] $Detail, # If set, returns system metadata about the -BuildID. [Parameter(Mandatory,ParameterSetName='build/builds/{buildId}/properties',ValueFromPipelineByPropertyName)] [switch] $BuildMetadata, # If set, will get artifacts from -BuildID. [Parameter(Mandatory,ParameterSetName='build/builds/{buildId}/artifacts',ValueFromPipelineByPropertyName)] [Alias('Artifacts')] [switch] $Artifact, # If set, will get a list of logs associated with -BuildID [Parameter(Mandatory,ParameterSetName='build/builds/{buildId}/logs')] [Alias('Logs')] [switch] $Log, # If provided, will retreive the specific log content of -BuildID [Parameter(Mandatory,ParameterSetName='build/builds/{buildId}/logs/{logId}',ValueFromPipelineByPropertyName)] [string] $LogID, # If set, will return the changeset associated with the build -BuildID. [Parameter(Mandatory,ParameterSetName='build/builds/{buildId}/changes')] [switch] $ChangeSet, # If set, will return the build report associated with -BuildID. [Parameter(Mandatory,ParameterSetName='build/builds/{buildId}/report')] [switch] $Report, # If set, will return the timeline for build -BuildID [Parameter(Mandatory,ParameterSetName='build/builds/{buildId}/timeline')] [switch] $Timeline, # If set, will return the code coverage associated with -BuildID [Parameter(Mandatory,ParameterSetName='test/codeCoverage')] [switch] $CodeCoverage, # If set, will get build definitions. [Parameter(Mandatory,ParameterSetName='build/definitions')] [switch] $Definition, # If set, will get a specific build by definition ID [Parameter(Mandatory,ParameterSetName='build/definitions/{definitionId}',ValueFromPipelineByPropertyName)] [Parameter(Mandatory,ParameterSetName='build/definitions/{definitionId}/properties',ValueFromPipelineByPropertyName)] [Parameter(Mandatory,ParameterSetName='build/definitions/{definitionId}/metrics',ValueFromPipelineByPropertyName)] [Parameter(Mandatory,ParameterSetName='build/definitions/{definitionId}/revisions',ValueFromPipelineByPropertyName)] [Parameter(Mandatory,ParameterSetName='build/status/{definitionId}',ValueFromPipelineByPropertyName)] [Parameter(Mandatory,ParameterSetName='build/definitions/{definitionId}/resources',ValueFromPipelineByPropertyName)] [string] $DefinitionID, # If set, will get the status of a defined build. [Parameter(Mandatory,ParameterSetName='build/status/{definitionId}')] [Alias('DefinitionStatus')] [switch] $Status, # If set, will get definition properties [Parameter(Mandatory,ParameterSetName='build/definitions/{definitionId}/properties')] [switch] $DefinitionMetadata, # If set, will get revisions to a build definition. [Parameter(Mandatory,ParameterSetName='build/definitions/{definitionId}/revisions')] [Alias('DefinitionRevisions','DefinitionRevision','Revisions')] [switch] $Revision, # If set, will get authorized resources for a build definition. [Parameter(Mandatory,ParameterSetName='build/definitions/{definitionId}/resources')] [switch] $Resource, # If set, will get metrics about a build definition. [Parameter(Mandatory,ParameterSetName='build/definitions/{definitionId}/metrics')] [Alias('DefinitionMetric','DefinitionMetrics','Metrics')] [switch] $Metric, # If provided, will get the first N builds or build definitions [Parameter(ParameterSetName='build/builds')] [Parameter(ParameterSetName='build/definitions')] [Alias('Top')] [Uint32] $First, # If provided, will only return builds for a given branch. [Parameter(ParameterSetName='build/builds')] [string] $BranchName, # If provided, will only return builds one of these tags. [Parameter(ParameterSetName='build/builds')] [string[]] $Tag, # If provided, will only return builds queued after this point in time. [Parameter(ParameterSetName='build/builds')] [Alias('MinTime')] [DateTime] $After, # If provided, will only return builds queued before this point in time. [Parameter(ParameterSetName='build/builds')] [Alias('MaxTime')] [DateTime] $Before, # If provided, will only return builds with this result. [Parameter(ParameterSetName='build/builds')] [ValidateSet('Canceled','Failed','None','Succeeded','PartiallySucceeded')] [string] $BuildResult, # If provided, will only return build definitions that have been built after this date. [Parameter(ParameterSetName='build/definitions')] [DateTime] $BuiltAfter, # If provided, will only return build definitions that have not been built since this date. [Parameter(ParameterSetName='build/definitions')] [Alias('NotBuiltAfter')] [DateTime] $NotBuiltSince, # If set, will return extended properities of a build definition. [Parameter(ParameterSetName='build/definitions')] [Alias('IncludeAllProperties')] [switch] $IncludeAllProperty, # If set, will include the latest build and latest completed build in a given build definition. [Parameter(ParameterSetName='build/definitions')] [Alias('IncludeLatestBuilds')] [switch] $IncludeLatestBuild, # If provided, will return build definition YAML. No other information will be returned. [Parameter(ParameterSetName='build/definitions/{definitionId}')] [switch] $DefinitionYAML) dynamicParam { . $GetInvokeParameters -DynamicParameter } begin { #region Copy Invoke-ADORestAPI parameters $invokeParams = . $getInvokeParameters $PSBoundParameters #endregion Copy Invoke-ADORestAPI parameters $authParams = @{} + $invokeParams $q = [Collections.Queue]::new() } process { $in = $_ $ParameterSet = $psCmdlet.ParameterSetName if ($ParameterSet -eq $MyInvocation.MyCommand.DefaultParameterSet) { if ($in.BuildID) { $ParameterSet = 'build/builds/{buildId}' $buildID = $psBoundParameters['BuildID'] = $in.BuildID } elseif ($in.DefinitionID) { $ParameterSet = 'build/definitions/{definitionId}' $definitionID = $psBoundParameters['DefinitionID'] = $in.DefinitionID } } $q.Enqueue(@{ParameterSet=$ParameterSet} + $PSBoundParameters) } end { $c, $t, $id = 0, $q.Count, [Random]::new().Next() while ($q.Count) { . $DQ $q # Pop one off the queue and declare all of it's variables (see /parts/DQ.ps1). if ($t -gt 1) { $c++ Write-Progress "Getting Builds" "$server $Organization $Project" -Id $id -PercentComplete ($c * 100/$t) } $invokeParams.Uri = # First construct the URI. It's made up of: "$(@( "$server".TrimEnd('/') # * The Server $Organization # * The Organization $Project # * The Project '_apis' #* '_apis' . $ReplaceRouteParameter $ParameterSet #* and the replaced route parameters. ) -join '/')?$( # Followed by a query string, containing @( if ($First) { "`$top=$first" } if ($CodeCoverage) { "buildId=$buildId" } if ($BranchName) { if ($BranchName -notlike '*/*') { $BranchName = "refs/heads/$branchName" } "branchName=$branchName" } if ($After) { "minTime=$($after.tolocalTime().ToString('o'))" } if ($before) { "maxTime=$($before.ToLocalTime().ToString('o'))" } if ($BuiltAfter) { "builtAfter=$($BuiltAfter.ToLocalTime().ToString('o'))" } if ($NotBuiltSince) { "notBuiltAfter=$($NotBuiltSince.ToLocalTime().ToString('o'))" } if ($IncludeAllProperty) { "includeAllProperties=true" } if ($IncludeLatestBuild) { "includeLatestBuilds=true" } if ($tag) { "tagFilters=$($tag -join ',')" } if ($BuildResult) { "resultFilter=$buildResult" } if ($Server -ne 'https://dev.azure.com/' -and -not $PSBoundParameters.ApiVersion) { $ApiVersion = '2.0' } if ($ApiVersion) { # an api-version (if one exists) "api-version=$ApiVersion" } ) -join '&' )" $subtypename = @($parameterSet -replace '/{\w+}', '' -split '/')[-1].TrimEnd('s') $subtypeName = if ($subtypename -eq 'Build') { '' } else { '.' + $subtypename.Substring(0,1).ToUpper() + $subtypename.Substring(1) } $invokeParams.PSTypeName = @( # Prepare a list of typenames so we can customize formatting: "$Organization.$Project.Build$subTypeName" # * $Organization.$Project.Build "$Organization.Build$subTypeName" # * $Organization.Build "PSDevOps.Build$subTypeName" # * PSDevOps.Build ) if ($IncludeAllProperty -or $DefinitionID) { if (-not $invokeParams.DecorateProperty) { $invokeParams.DecorateProperty = @{} } $invokeParams.DecorateProperty.Repository = "$Organization.$project.Repository", "$Organization.Repository", "PSDevOps.Repository" } if ($Detail) { $null = $PSBoundParameters.Remove('Detail') Invoke-ADORestAPI @invokeParams -Property @{ Organization = $Organization Project = $Project Server = $Server } | Add-Member NoteProperty ChangeSet -Value (Get-ADOBuild @PSBoundParameters -ChangeSet) -Force -PassThru | Add-Member NoteProperty Timeline -Value (Get-ADOBuild @PSBoundParameters -Timeline) -Force -PassThru | Add-Member NoteProperty Artifacts -Value (Get-ADOBuild @PSBoundParameters -Artifact) -Force -PassThru | Add-Member NoteProperty Logs -Value (Get-ADOBuild @PSBoundParameters -Log) -Force -PassThru | Add-Member NoteProperty CodeCoverage -Value (Get-ADOBuild @PSBoundParameters -CodeCoverage) -Force -PassThru } elseif ($DefinitionYAML) { $definitionObject = Invoke-ADORestAPI @invokeParams if ($definitionObject.process.yamlFileName) { $repoParams = @{ Organization = $Organization Project = $Project ProviderName = $definitionObject.repository.type RepositoryName = $definitionObject.repository.name Path = $definitionObject.process.yamlfilename CommitOrBranch = $definitionObject.repository.defaultBranch } if ($definitionObject.repository.properties.connectedServiceId) { $repoParams.EndpointId = $definitionObject.repository.properties.connectedServiceId } # Get the repository, and redirect errors into output. Get-ADORepository @repoParams @authParams 2>&1 | # This way, we can add properties: Add-Member NoteProperty Organization $Organization -Force -PassThru | # * .Organization Add-Member NoteProperty Project $Project -Force -PassThru | # .Project Add-Member NoteProperty DefinitionID $definitionObject.ID -Force -PassThru | # .DefinitionID Add-Member NoteProperty DefinitionName $definitionObject.Name -Force -PassThru # .DefinitionName } } else { Invoke-ADORestAPI @invokeParams -Property @{ Organization = $Organization Project = $Project Server = $Server } } } if ($t -gt 1) { $c++ Write-Progress "Getting Builds" "$server $Organization $Project" -Id $id -Completed } } } |