-
Notifications
You must be signed in to change notification settings - Fork 346
Expand file tree
/
Copy pathverify-nupkgs.ps1
More file actions
306 lines (250 loc) · 12.1 KB
/
verify-nupkgs.ps1
File metadata and controls
306 lines (250 loc) · 12.1 KB
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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
[CmdletBinding()]
Param(
[Parameter(Mandatory)]
[ValidateSet("Debug", "Release")]
[string] $configuration,
[Parameter(Mandatory)]
[string] $versionPrefix,
[Parameter(Mandatory)]
[string] $currentBranch
)
$ErrorActionPreference = 'Stop'
Add-Type -AssemblyName System.IO.Compression.FileSystem
function Verify-Nuget-Packages {
Write-Host "Starting Verify-Nuget-Packages."
$expectedNumOfFiles = @{
"Microsoft.CodeCoverage" = 75
"Microsoft.NET.Test.Sdk" = 25
"Microsoft.TestPlatform" = 538
"Microsoft.VisualStudio.TestTools.TestPlatform.V2.CLI" = 380
"Microsoft.TestPlatform.Build" = 20
"Microsoft.TestPlatform.CLI" = 481
"Microsoft.TestPlatform.Extensions.TrxLogger" = 34
"Microsoft.TestPlatform.ObjectModel" = 92
"Microsoft.TestPlatform.AdapterUtilities" = 61
"Microsoft.TestPlatform.Portable" = 608
"Microsoft.TestPlatform.TestHost" = 63
"Microsoft.TestPlatform.TranslationLayer" = 122
"Microsoft.TestPlatform.Internal.Uwp" = 38
}
$packageDirectory = Resolve-Path "$PSScriptRoot/../artifacts/packages/$configuration"
$tmpDirectory = Resolve-Path "$PSScriptRoot/../artifacts/tmp/$configuration"
$pattern = "*.$versionPrefix*.nupkg"
$nugetPackages = @(Get-ChildItem $packageDirectory -Filter $pattern -Recurse -File | Where-Object { $_.Name -notLike "*.symbols.nupkg"})
if (0 -eq $nugetPackages.Length) {
throw "No nuget packages matching $pattern were found in '$packageDirectory'."
}
$suffixes = @($nugetPackages -replace ".*?$([regex]::Escape($versionPrefix))(.*)\.nupkg", '$1' | Sort-Object -Unique)
if (1 -lt $suffixes.Length) {
Write-Host "There are two different suffixes matching the same version prefix: '$($suffixes -join "', '")'".
$latestNuget = $nugetPackages |
Where-Object { $_.Name -like "Microsoft.TestPlatform.ObjectModel.*" } |
Sort-Object -Property LastWriteTime -Descending |
Select-Object -First 1
$suffix = $suffixes | Where { $latestNuget.Name.Contains("$versionPrefix$_.nupkg") }
$version = "$versionPrefix$suffix"
Write-Host "The most recently written Microsoft.TestPlatform.ObjectModel.* nuget, is $($latestNuget.Name), which has '$suffix' suffix. Selecting only packages with that suffix."
$nugetPackages = $nugetPackages | Where-Object { $_.Name -like "*$version.nupkg" }
}
else {
$suffix = $suffixes[0]
$version = "$versionPrefix$suffix"
}
Write-Host "Found $(@($nugetPackages).Count) nuget packages:`n $($nugetPackages.FullName -join "`n ")"
# In source build we don't build this.
$vsix = Get-Item "$PSScriptRoot/../artifacts/VSSetup/$configuration/Insertion/Microsoft.VisualStudio.TestTools.TestPlatform.V2.CLI.vsix" -ErrorAction Ignore
if ($vsix) {
$nugetPackages += $vsix
}
Write-Host "Unzipping NuGet packages to '$tmpDirectory'."
$unzipNugetPackageDirs = @()
foreach ($nugetPackage in $nugetPackages) {
$unzipNugetPackageDir = Join-Path $tmpDirectory $nugetPackage.BaseName
$unzipNugetPackageDirs += $unzipNugetPackageDir
if (Test-Path -Path $unzipNugetPackageDir) {
Remove-Item -Force -Recurse $unzipNugetPackageDir
}
Unzip $nugetPackage.FullName $unzipNugetPackageDir
}
Write-Host "Verify NuGet packages files."
$errors = @()
foreach ($unzipNugetPackageDir in $unzipNugetPackageDirs) {
try {
$packageBaseName = (Get-Item $unzipNugetPackageDir).BaseName
$packageKey = $packageBaseName.Replace([string]".$version", [string]"")
Write-Host "Verifying package '$packageBaseName'."
$actualNumOfFiles = (Get-ChildItem -Recurse -File -Path $unzipNugetPackageDir | Where-Object { $_.Name -ne '.signature.p7s' }).Count
if (-not $expectedNumOfFiles.ContainsKey($packageKey)) {
$errors += "Package '$packageKey' is not present in file expectedNumOfFiles table. Is that package known?"
continue
}
if ($expectedNumOfFiles[$packageKey] -ne $actualNumOfFiles) {
$errors += "Number of files are not equal for '$packageBaseName', expected: $($expectedNumOfFiles[$packageKey]) actual: $actualNumOfFiles"
}
if ($packageKey -eq "Microsoft.TestPlatform") {
Verify-Version -nugetDir $unzipNugetPackageDir -errors $errors
}
}
finally {
# if ($null -ne $unzipNugetPackageDir -and (Test-Path $unzipNugetPackageDir)) {
# Remove-Item -Force -Recurse $unzipNugetPackageDir | Out-Null
# }
}
}
if ($errors) {
Write-Error "There are $($errors.Count) errors:`n$($errors -join "`n")"
}
Write-Host "Completed Verify-Nuget-Packages."
$unzipNugetPackageDirs
}
function Unzip {
param([string]$zipfile, [string]$outpath)
Write-Verbose "Unzipping '$zipfile' to '$outpath'."
[System.IO.Compression.ZipFile]::ExtractToDirectory($zipfile, $outpath)
}
function Match-VersionAgainstBranch {
param ([string]$vsTestVersion, [string]$branchName, [string[]]$errors)
# Output useful info.
Write-Host "VSTest Product Version: `"$vsTestVersion`""
Write-Host "Current Branch: `"$branchName`""
$versionIsRTM = $vsTestVersion -match "^\d+\.\d+\.\d+$"
$versionIsRelease = $vsTestVersion -match "^\d+\.\d+\.\d+\-release\-\d{8}\-\d{2}$"
$versionIsPreview = $vsTestVersion -match "^\d+\.\d+\.\d+\-preview\-\d{8}\-\d{2}$"
$isReleaseBranch = $branchName -like "rel/*"
$isPreviewBranch = $branchName -like "main"
if (!$isReleaseBranch -and !$isPreviewBranch) {
Write-Host "Skipping check since branch is neither `"release`" nor `"preview`""
return
}
Write-Host "Matching branch against product version ... "
if ($isReleaseBranch -and !$versionIsRTM -and !$versionIsRelease) {
$errors += "Release version `"$vsTestVersion`" should either be RTM, or contain a `"release`" suffix."
}
if ($isPreviewBranch -and !$versionIsPreview) {
$errors += "Preview version `"$vsTestVersion`" should contain a `"preview`" suffix."
}
}
function Verify-Version {
param ([string]$nugetDir, [string[]] $errors)
$vsTestExe = "$nugetDir/tools/net462/Common7/IDE/Extensions/TestPlatform/vstest.console.exe"
$vsTestProductVersion = (Get-Item $vsTestExe).VersionInfo.ProductVersion
Match-VersionAgainstBranch -vsTestVersion $vsTestProductVersion -branchName $currentBranch -errors $errors
}
function Verify-NugetPackageExe {
param(
[Parameter(Mandatory)]
[ValidateSet("Debug", "Release")]
[string] $configuration,
$UnzipNugetPackages
)
$exclusions = @{
"CodeCoverage\CodeCoverage.exe" = "x86"
"Dynamic Code Coverage Tools\CodeCoverage.exe" = "x86"
"amd64\CodeCoverage.exe" = "x64"
"IntelliTrace.exe" = "x86"
"ProcessSnapshotCleanup.exe" = "x86-64"
"TDEnvCleanup.exe" = "x86"
"TestPlatform\SettingsMigrator.exe" = "x86"
"dump\DumpMinitool.exe" = "x86-64"
}
$errs = @()
$exes = $UnzipNugetPackages | Get-ChildItem -Filter *.exe -Recurse -Force
if (0 -eq @($exes).Length) {
throw "No exe files were found."
}
# use wow programfiles because they always point to x64 programfiles where VS is installed
$dumpBin = Get-ChildItem -Recurse -Force -Filter dumpbin.exe -path "$env:ProgramW6432\Microsoft Visual Studio\2022\Enterprise" | Select-Object -First 1
if (-not $dumpBin) {
throw "Did not find dumpbin.exe in '$env:ProgramW6432\Microsoft Visual Studio\2022\Enterprise'."
}
$corFlags = Get-ChildItem -Recurse -Force -Filter CorFlags.exe -path "${env:ProgramFiles(x86)}\Microsoft SDKs\Windows" | Select-Object -First 1
if (-not $corFlags) {
throw "Did not find CorFlags.exe in '${env:ProgramFiles(x86)}\Microsoft SDKs\Windows'."
}
$exes | ForEach-Object {
$m = & $dumpBin /headers $_.FullName | Select-String "machine \((.*)\)"
if (-not $m.Matches.Success) {
$err = "Did not find the platform of the exe $fullName)."
}
$platform = $m.Matches.Groups[1].Value
$fullName = $_.FullName
$name = $_.Name
if ("x86" -eq $platform) {
$corFlagsOutput = & $corFlags $fullName
# this is an native x86 exe or a .net x86 that requires of prefers 32bit
$platform = if ($corFlagsOutput -like "*does not have a valid managed header*" -or $corFlagsOutput -like "*32BITREQ : 1*" -or $corFlagsOutput -like "*32BITPREF : 1*") {
# this is an native x86 exe or a .net x86 that requires of prefers 32bit
"x86" } else {
# this is a x86 executable that is built as AnyCpu and does not prefer 32-bit so it will run as x64 on 64-bit system.
"x86-64" }
}
if (($pair = $exclusions.GetEnumerator() | Where-Object { $fullName -like "*$($_.Name)" })) {
if (1 -lt $($pair).Count) {
$err = "Too many paths matched the query, only one match is allowed. Matches: $($pair.Name)"
$errs += $err
Write-Host -ForegroundColor Red Error: $err
}
if ($platform -ne $pair.Value) {
$err = "$fullName must have architecture $($pair.Value), but it was $platform."
$errs += $err
Write-Host -ForegroundColor Red Error: $err
}
}
elseif ("x86" -eq $platform) {
if ($name -notlike "*x86*") {
$err = "$fullName has architecture $platform, and must contain x86 in the name of the executable."
$errs += $err
Write-Host -ForegroundColor Red Error: $err
}
}
elseif ($platform -in "x64", "x86-64") {
if ($name -like "*x86*" -or $name -like "*arm64*") {
$err = "$fullName has architecture $platform, and must NOT contain x86 or arm64 in the name of the executable."
$errs += $err
Write-Host -ForegroundColor Red Error: $err
}
}
elseif ("arm64" -eq $platform) {
if ($name -notlike "*arm64*") {
$err = "$fullName has architecture $platform, and must contain arm64 in the name of the executable."
$errs += $err
Write-Host -ForegroundColor Red Error: $err
}
}
else {
$err = "$fullName has unknown architecture $platform."
$errs += $err
Write-Host -ForegroundColor Red $err
}
"Success: $name is $platform - $fullName"
}
if ($errs) {
throw "Fail!:`n$($errs -join "`n")"
}
}
function Verify-NugetPackageVersion {
param(
[Parameter(Mandatory)]
[ValidateSet("Debug", "Release")]
[string] $configuration,
$UnzipNugetPackages
)
# look for vstest.console.dll because unified build for .NET does not produce vstest.console.exe
$exes = $UnzipNugetPackages | Get-ChildItem -Filter vstest.console.dll -Recurse -Force
if (0 -eq @($exes).Length) {
throw "No vstest.console.dll files were found."
}
$exes | ForEach-Object {
if ($_.VersionInfo.ProductVersion.Contains("+")) {
throw "$_ contains '+' in the ProductVersion $($_.VersionInfo.ProductVersion), this breaks DTAAgent in AzDO."
}
else {
"$_ version $($_.VersionInfo.ProductVersion) is ok."
}
}
}
$unzipNugetPackages = Verify-Nuget-Packages
Start-sleep -Seconds 10
# skipped, it is hard to find the right dumpbin.exe and corflags tools on server
# Verify-NugetPackageExe -configuration $configuration -UnzipNugetPackages $unzipNugetPackages
Verify-NugetPackageVersion -configuration $configuration -UnzipNugetPackages $unzipNugetPackages