Modules/Wait-VstsBuild.psm1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
. "$PSScriptRoot\Test-Environment.ps1"

<#
.SYNOPSIS
Pauses the script until the specified build is complete.
 
.DESCRIPTION
Pauses the script util the specified build is complete. If the build is in-progress then a progess bar is displayed. If the build failes then the reason is reported to the console.
 
.PARAMETER build
The name of the build definition to monitor.
 
.PARAMETER buildNumber
If specified then this build instance is checked, otherwise the latest build is monitored.
 
.PARAMETER pipeBuild
If specified then the build result is piped to output
 
.EXAMPLE
Wait-VstsBuild 'BuildDefinitionName' -buildNumber '201709.08.1-develop' -pipeBuild
 
#>

function Wait-VstsBuild () { 
    [CmdletBinding(PositionalBinding = $false)]
    param(
        [string]$buildNumber = $null,
        [switch]
        [bool]$pipeBuild = $false
    )
    DynamicParam {
        Test-Environment
        # Set the dynamic parameters' name
        $ParameterName = 'build'
        
        # Create the dictionary
        $RuntimeParameterDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary

        # Create the collection of attributes
        $AttributeCollection = New-Object System.Collections.ObjectModel.Collection[System.Attribute]
        
        # Create and set the parameters' attributes
        $ParameterAttribute = New-Object System.Management.Automation.ParameterAttribute
        $ParameterAttribute.Mandatory = $true
        $ParameterAttribute.Position = 0
        $AttributeCollection.Add($ParameterAttribute)

        # Add the attributes to the attributes collection

        # Generate and set the ValidateSet
        Write-Debug $MyInvocation.MyCommand.Module.PrivateData.buildDefinitions.Keys
        $ValidateSetAttribute = [System.Management.Automation.ValidateSetAttribute]::new($MyInvocation.MyCommand.Module.PrivateData.buildDefinitions.Keys)

        # Add the ValidateSet to the attributes collection
        $AttributeCollection.Add($ValidateSetAttribute)

        # Create and return the dynamic parameter
        $RuntimeParameter = New-Object System.Management.Automation.RuntimeDefinedParameter($ParameterName, [string], $AttributeCollection)
        $RuntimeParameterDictionary.Add($ParameterName, $RuntimeParameter)
        return $RuntimeParameterDictionary
        
    }
    begin {
        $build = $PSBoundParameters[$ParameterName]
        $definitionId = $MyInvocation.MyCommand.Module.PrivateData.buildDefinitions[$build]
    }
    process {
        # $v = Get-VstsConnection
        $urlBuild = "_apis/build/builds?definitions=$($definitionId)&`$top=1"
        if ($buildNumber -ne $null) {
            $urlBuild += "&buildNumber=$buildNumber"
        }
        $buildResponse = Get-RestVsts -U $urlBuild -V 2.0
        if ($buildResponse.Count -eq 0) {
            Write-Host "No builds found for $build"
            return
        }
        $latestBuild = $buildResponse.value[0];
        $buildId = $latestBuild.id
        $done = $false
        $activity = "Compiling $($latestBuild.buildNumber)"
        Write-Host $activity
        $currentOperation = "Starting"
        $timelineResponse = $null
        while (-not $done) {
            # $timelineResponse = Invoke-RestMethod -Method Get -Uri $urlTimeline -ContentType 'application/json' -Headers $v.RequestHeaders -Verbose:$VerbosePreference
            $timelineResponse = Get-RestVsts -U "_apis/build/builds/$buildId/timeline" -V 2.0
            $done = $true
            [float]$steps = $timelineResponse.records.Count
            [float]$completed = 0
            foreach ($record in $timelineResponse.records | Sort-Object order) {
                if ($record.state -eq "completed") {
                    $completed++
                }
                elseif ($record.state -eq "inProgress") {
                    $currentOperation = $record.name
                }
            }
            if ($steps -ne $completed) {
                Write-Progress -Activity $activity -PercentComplete ($completed / $steps * 100) -CurrentOperation $currentOperation
                $done = $false
                Start-Sleep -Seconds 1
            }
        }
        Write-Progress -Activity $activity -Completed
        "Build $($latestBuild.buildNumber) $($latestBuild.result)"
        if ($timelineResponse -ne $null) {
            foreach ($record in $timelineResponse.records) {
                if ($record.result -ne "succeeded") {
                    $record.name
                    foreach ($issue in $record.issues) { 
                        switch ($issue.type) {
                            "warning" { Write-Host "$($issue.type): $($issue.message)" -ForegroundColor Yellow }
                            "error" { Write-Host "$($issue.type): $($issue.message)" -ForegroundColor Red }
                            Default { Write-Host "$($issue.type): $($issue.message)"}
                        }
                        
                    }
                }
            }
        }
        if ($pipeBuild) {
            $buildResponse = Get-RestVsts -U $urlBuild -V 2.0
            $latestBuild = $buildResponse.value[0];        
            Write-Output $latestBuild  
        }      
    }
}