@@ -8,31 +8,37 @@ param (
8
8
Set-StrictMode - version 2.0
9
9
$ErrorActionPreference = " Stop"
10
10
11
- try {
12
- # build map of all *.vsman files to their `info.buildVersion` values
13
- $manifestVersionMap = @ {}
14
- Get-ChildItem - Path " $insertionDir \*" - Filter " *.vsman" | ForEach-Object {
15
- $manifestName = Split-Path $_ - Leaf
16
- $vsmanContents = Get-Content $_ | ConvertFrom-Json
17
- $buildVersion = $vsmanContents.info.buildVersion
18
- $manifestVersionMap.Add ($manifestName , $buildVersion )
19
- }
11
+ $dropUrlRegex = " (https://vsdrop\.corp\.microsoft\.com/[^\r\n;]+);([^\r\n]+)\r?\n"
20
12
21
- # find all publish URLs
22
- $manifests = @ ()
23
- $seenManifests = @ {}
24
- $url = " https://dev.azure.com/dnceng/internal/_apis/build/builds/$buildId /logs?api-version=5.1"
13
+ function Invoke-WebRequestWithAccessToken ([string ] $uri , [string ] $accessToken , [int ] $retryCount = 5 ) {
14
+ Write-Host " Fetching content from $uri "
25
15
$base64 = [Convert ]::ToBase64String([System.Text.Encoding ]::ASCII.GetBytes(" :$accessToken " ))
26
16
$headers = @ {
27
17
Authorization = " Basic $base64 "
28
18
}
29
- Write-Host " Fetching log from $url "
30
- $json = Invoke-WebRequest - Method Get - Uri $url - Headers $headers - UseBasicParsing | ConvertFrom-Json
19
+
20
+ for ($i = 0 ; $i -lt $retryCount ; $i ++ ) {
21
+ try {
22
+ return Invoke-WebRequest - Method Get - Uri $uri - Headers $headers - UseBasicParsing
23
+ }
24
+ catch {
25
+ Write-Host " Invoke-WebRequest failed: $_ "
26
+ Start-Sleep - Seconds 1
27
+ }
28
+ }
29
+
30
+ throw " Unable to fetch $uri after $retryCount tries."
31
+ }
32
+
33
+ # this function has to download ~500 individual logs and check each one; prone to timeouts
34
+ function Get-ManifestsViaIndividualLogs ([PSObject ] $manifestVersionMap , [string ] $buildId , [string ] $accessToken ) {
35
+ $manifests = @ ()
36
+ $seenManifests = @ {}
37
+ $json = Invoke-WebRequestWithAccessToken - uri " https://dev.azure.com/dnceng/internal/_apis/build/builds/$buildId /logs?api-version=5.1" - accessToken $accessToken | ConvertFrom-Json
31
38
foreach ($l in $json.value ) {
32
39
$logUrl = $l.url
33
- Write-Host " Fetching log from $logUrl "
34
- $log = (Invoke-WebRequest - Method Get - Uri $logUrl - Headers $headers - UseBasicParsing).Content
35
- If ($log -Match " (https://vsdrop\.corp\.microsoft\.com/[^\r\n;]+);([^\r\n]+)\r?\n" ) {
40
+ $log = (Invoke-WebRequestWithAccessToken - uri $logUrl - accessToken $accessToken ).Content
41
+ If ($log -Match $dropUrlRegex ) {
36
42
$manifestShortUrl = $Matches [1 ]
37
43
$manifestName = $Matches [2 ]
38
44
$manifestUrl = " $manifestShortUrl ;$manifestName "
45
51
}
46
52
}
47
53
54
+ return $manifests
55
+ }
56
+
57
+ # this function only has to download 1 file and look at a very specific file
58
+ function Get-ManifestsViaZipLog ([PSObject ] $manifestVersionMap , [string ] $buildId , [string ] $accessToken ) {
59
+ # create temporary location
60
+ $guid = [System.Guid ]::NewGuid().ToString()
61
+ $tempDir = Join-Path ([System.IO.Path ]::GetTempPath()) $guid
62
+ New-Item - ItemType Directory - Path $tempDir | Out-Null
63
+
64
+ # download the logs
65
+ $base64 = [Convert ]::ToBase64String([System.Text.Encoding ]::ASCII.GetBytes(" :$accessToken " ))
66
+ $headers = @ {
67
+ Authorization = " Basic $base64 "
68
+ }
69
+ $uri = " https://dev.azure.com/dnceng/internal/_apis/build/builds/$buildId /logs?`$ format=zip"
70
+ Invoke-WebRequest - Uri $uri - Method Get - Headers $headers - UseBasicParsing - OutFile " $tempDir /logs.zip"
71
+
72
+ # expand the logs
73
+ New-Item - ItemType Directory - Path " $tempDir /logs" | Out-Null
74
+ Expand-Archive - Path " $tempDir /logs.zip" - DestinationPath " $tempDir /logs"
75
+
76
+ # parse specific logs
77
+ $logDir = " $tempDir /logs"
78
+ $manifests = @ ()
79
+ $seenManifests = @ {}
80
+ Get-ChildItem $logDir - r - inc " *Upload VSTS Drop*" | ForEach-Object {
81
+ $result = Select-String - Path $_ - Pattern " (https://vsdrop\.corp\.microsoft\.com[^;]+);(.*)" - AllMatches
82
+ $result.Matches | ForEach-Object {
83
+ $manifestShortUrl = $_.Groups [1 ].Value
84
+ $manifestName = $_.Groups [2 ].Value
85
+ $manifestUrl = " $manifestShortUrl ;$manifestName "
86
+ If (-Not $seenManifests.Contains ($manifestUrl )) {
87
+ $seenManifests.Add ($manifestUrl , $true )
88
+ $buildVersion = $manifestVersionMap [$manifestName ]
89
+ $manifestEntry = " $manifestName {$buildVersion }=$manifestUrl "
90
+ $manifests += $manifestEntry
91
+ }
92
+ }
93
+ }
94
+
95
+ Remove-Item - Path $tempDir - Recurse
96
+
97
+ return $manifests
98
+ }
99
+
100
+ try {
101
+ # build map of all *.vsman files to their `info.buildVersion` values
102
+ $manifestVersionMap = @ {}
103
+ Get-ChildItem - Path " $insertionDir \*" - Filter " *.vsman" | ForEach-Object {
104
+ $manifestName = Split-Path $_ - Leaf
105
+ $vsmanContents = Get-Content $_ | ConvertFrom-Json
106
+ $buildVersion = $vsmanContents.info.buildVersion
107
+ $manifestVersionMap.Add ($manifestName , $buildVersion )
108
+ }
109
+
110
+ # find all publish URLs
111
+ # $manifests = Get-ManifestsViaIndividualLogs -manifestVersionMap $manifestVersionMap -buildId $buildId -accessToken $accessToken
112
+ $manifests = Get-ManifestsViaZipLog - manifestVersionMap $manifestVersionMap - buildId $buildId - accessToken $accessToken
113
+
48
114
$final = $manifests -Join " ,"
49
115
Write-Host " Setting InsertJsonValues to $final "
50
116
Write-Host " ##vso[task.setvariable variable=InsertJsonValues]$final "
0 commit comments