4949 variables :
5050 netFxDir : $(Build.SourcesDirectory)\coverageNetFx
5151 netCoreDir : $(Build.SourcesDirectory)\coverageNetCore
52+ # The first-run telemetry notice is written to stderr, which PowerShell
53+ # surfaces as an error record and fails the step.
54+ DOTNET_COVERAGE_TELEMETRY_OPTOUT : 1
5255
5356 steps :
5457 - ${{if eq(parameters.debug, true)}} :
@@ -68,10 +71,30 @@ jobs:
6871 debug : ${{ parameters.debug }}
6972
7073 # Install additional dotnet tools.
71- - pwsh : |
72- dotnet tool install --global dotnet-coverage
73- dotnet tool install --global dotnet-reportgenerator-globaltool
74- displayName: Install dotnet tools
74+ #
75+ # The dotnet CLI tool tasks need a working directory that contains at most
76+ # one project file, but they must still obey the repo's NuGet.config. We
77+ # copy the NuGet.config to a temp dir and run the tasks from there; the
78+ # tools are still installed globally for subsequent steps to use.
79+ #
80+ - pwsh : Copy-Item "$(Build.SourcesDirectory)\NuGet.config" "$(Agent.TempDirectory)\"
81+ displayName : Copy NuGet.config for tool installs
82+
83+ - task : DotNetCoreCLI@2
84+ displayName : Install dotnet-coverage tool
85+ inputs :
86+ command : custom
87+ custom : tool
88+ workingDirectory : $(Agent.TempDirectory)
89+ arguments : install --global dotnet-coverage --version 18.9.0
90+
91+ - task : DotNetCoreCLI@2
92+ displayName : Install dotnet-reportgenerator tool
93+ inputs :
94+ command : custom
95+ custom : tool
96+ workingDirectory : $(Agent.TempDirectory)
97+ arguments : install --global dotnet-reportgenerator-globaltool --version 5.5.11
7598
7699 - ${{ each targetFramework in parameters.targetFrameworks }} :
77100 - task : DownloadPipelineArtifact@2
@@ -120,20 +143,33 @@ jobs:
120143 foreach ($file in $toProcess){
121144 $jobs += Start-ThreadJob -ScriptBlock {
122145 $params = $using:file
123- & dotnet-coverage merge $($params.File) --output $($params.OutputFile) --output-format xml
146+ # Redirect stderr into stdout so informational tool output
147+ # isn't surfaced as a PowerShell error record.
148+ $out = & dotnet-coverage merge $($params.File) --output $($params.OutputFile) --output-format xml 2>&1
149+ $exitCode = $LASTEXITCODE
150+ $out | Out-String | Write-Output
151+ if ($exitCode -ne 0) {
152+ throw "dotnet-coverage merge failed with exit code $exitCode for $($params.File)."
153+ }
124154 }
125155 }
126156
127157 if ($jobs.Count -eq 0) {
128- Write-Error "No .coverage files found in $InputDirectoryPath. Cannot merge."
129- exit 1
158+ throw "No .coverage files found in $InputDirectoryPath. Cannot merge."
130159 }
131160
132161 Write-Host "Merging started..."
133- Wait-Job -Job $jobs
162+ $null = Wait-Job -Job $jobs
163+
164+ $failed = @($jobs | Where-Object { $_.State -ne 'Completed' })
134165
135166 foreach ($job in $jobs) {
136- Receive-Job -Job $job -Wait -AutoRemoveJob
167+ Receive-Job -Job $job -ErrorAction Continue 2>&1 | Out-String | Write-Host
168+ Remove-Job -Job $job -Force
169+ }
170+
171+ if ($failed.Count -gt 0) {
172+ throw "$($failed.Count) of $($jobs.Count) merge jobs failed for $InputDirectoryPath."
137173 }
138174 }
139175
@@ -155,24 +191,40 @@ jobs:
155191 displayName: '[Debug] List converted files'
156192
157193 - pwsh : |
158- $jobs = @()
159- $jobs += Start-ThreadJob -ScriptBlock {
160- & reportgenerator "-reports:coverageNetFxXml\*.coveragexml" "-targetdir:coveragereportNetFx" "-reporttypes:Cobertura;" "-assemblyfilters:+microsoft.data.sqlclient.dll" "-sourcedirs:$(Build.SourcesDirectory)\src\Microsoft.Data.SqlClient\netfx\src;$(Build.SourcesDirectory)\src\Microsoft.Data.SqlClient\src" "-classfilters:+Microsoft.Data.*"
161- }
162-
163- $jobs += Start-ThreadJob -ScriptBlock {
164- & reportgenerator "-reports:coverageNetCoreXml\*.coveragexml" "-targetdir:coveragereportNetCore" "-reporttypes:Cobertura;" "-assemblyfilters:+microsoft.data.sqlclient.dll" "-sourcedirs:$(Build.SourcesDirectory)\src\Microsoft.Data.SqlClient\netcore\src;$(Build.SourcesDirectory)\src\Microsoft.Data.SqlClient\src" "-classfilters:+Microsoft.Data.*"
194+ function StartReportGenerator {
195+ param([string[]]$Arguments)
196+
197+ Start-ThreadJob -ArgumentList @(,$Arguments) -ScriptBlock {
198+ param([string[]]$reportGeneratorArgs)
199+
200+ # Redirect stderr into stdout so informational tool output isn't
201+ # surfaced as a PowerShell error record.
202+ $out = & reportgenerator @reportGeneratorArgs 2>&1
203+ $exitCode = $LASTEXITCODE
204+ $out | Out-String | Write-Output
205+ if ($exitCode -ne 0) {
206+ throw "reportgenerator failed with exit code $exitCode."
207+ }
208+ }
165209 }
166210
167- $jobs += Start-ThreadJob -ScriptBlock {
168- & reportgenerator "-reports:coverageNetCoreXml\*.coveragexml" "-targetdir:coveragereportAddOns" "-reporttypes:Cobertura;" "-assemblyfilters:+microsoft.data.sqlclient.alwaysencrypted.azurekeyvaultprovider.dll" "-sourcedirs:$(Build.SourcesDirectory)\src\Microsoft.Data.SqlClient\add-ons\AzureKeyVaultProvider" "-classfilters:+Microsoft.Data.*"
169- }
211+ $jobs = @()
212+ $jobs += StartReportGenerator @("-reports:coverageNetFxXml\*.coveragexml", "-targetdir:coveragereportNetFx", "-reporttypes:Cobertura;", "-assemblyfilters:+microsoft.data.sqlclient.dll", "-sourcedirs:$(Build.SourcesDirectory)\src\Microsoft.Data.SqlClient\netfx\src;$(Build.SourcesDirectory)\src\Microsoft.Data.SqlClient\src", "-classfilters:+Microsoft.Data.*")
213+ $jobs += StartReportGenerator @("-reports:coverageNetCoreXml\*.coveragexml", "-targetdir:coveragereportNetCore", "-reporttypes:Cobertura;", "-assemblyfilters:+microsoft.data.sqlclient.dll", "-sourcedirs:$(Build.SourcesDirectory)\src\Microsoft.Data.SqlClient\netcore\src;$(Build.SourcesDirectory)\src\Microsoft.Data.SqlClient\src", "-classfilters:+Microsoft.Data.*")
214+ $jobs += StartReportGenerator @("-reports:coverageNetCoreXml\*.coveragexml", "-targetdir:coveragereportAddOns", "-reporttypes:Cobertura;", "-assemblyfilters:+microsoft.data.sqlclient.alwaysencrypted.azurekeyvaultprovider.dll", "-sourcedirs:$(Build.SourcesDirectory)\src\Microsoft.Data.SqlClient\add-ons\AzureKeyVaultProvider", "-classfilters:+Microsoft.Data.*")
170215
171216 Write-Host "Running ReportGenerator..."
172- Wait-Job -Job $jobs
217+ $null = Wait-Job -Job $jobs
218+
219+ $failed = @($jobs | Where-Object { $_.State -ne 'Completed' })
173220
174221 foreach ($job in $jobs) {
175- Receive-Job -Job $job -Wait -AutoRemoveJob
222+ Receive-Job -Job $job -ErrorAction Continue 2>&1 | Out-String | Write-Host
223+ Remove-Job -Job $job -Force
224+ }
225+
226+ if ($failed.Count -gt 0) {
227+ throw "$($failed.Count) of $($jobs.Count) ReportGenerator jobs failed."
176228 }
177229
178230 Write-Host "Removing merged XML files..."
0 commit comments