@@ -8,31 +8,37 @@ param (
88Set-StrictMode - version 2.0
99$ErrorActionPreference = " Stop"
1010
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"
2012
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 "
2515 $base64 = [Convert ]::ToBase64String([System.Text.Encoding ]::ASCII.GetBytes(" :$accessToken " ))
2616 $headers = @ {
2717 Authorization = " Basic $base64 "
2818 }
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
3138 foreach ($l in $json.value ) {
3239 $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 ) {
3642 $manifestShortUrl = $Matches [1 ]
3743 $manifestName = $Matches [2 ]
3844 $manifestUrl = " $manifestShortUrl ;$manifestName "
4551 }
4652 }
4753
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+
48114 $final = $manifests -Join " ,"
49115 Write-Host " Setting InsertJsonValues to $final "
50116 Write-Host " ##vso[task.setvariable variable=InsertJsonValues]$final "
0 commit comments