|
| 1 | +#!/usr/bin/env pwsh |
1 | 2 | #Requires -Version 5.1 |
2 | 3 |
|
3 | | -param( |
4 | | - [ValidateSet('Build','BuildAll','CI','FormatSource','PackageRestore','Packages','Restore','Test', |
5 | | - '_AnalyzeSource', '_Packages','_Publish','_PushPackages','_SignPackages','_Test32','_Test64','_TestCore')] |
6 | | - [string]$target = "BuildAll", |
7 | | - [string]$configuration = "Release" |
8 | | -) |
9 | | - |
10 | 4 | Set-StrictMode -Version Latest |
11 | 5 | $ErrorActionPreference = "Stop" |
12 | 6 |
|
13 | | -if ($null -eq $PSScriptRoot) { |
14 | | - write-host "This build script requires PowerShell 3 or later." -ForegroundColor Red |
15 | | - exit -1 |
16 | | -} |
17 | | - |
18 | | -Set-Location $PSScriptRoot |
19 | | - |
20 | | -$packageOutputFolder = (join-path (Get-Location) "artifacts\packages") |
21 | | -$parallelFlags = "-parallel all" |
22 | | -$nonparallelFlags = "-parallel collections" |
23 | | -$testOutputFolder = (join-path (Get-Location) "artifacts\test") |
24 | | -$dotnetFormatCommand = "& dotnet dotnet-format --folder --exclude src/common/AssemblyResolution/Microsoft.DotNet.PlatformAbstractions --exclude src/common/AssemblyResolution/Microsoft.Extensions.DependencyModel --exclude src/xunit.assert/Asserts" |
25 | | - |
26 | | -# Helper functions |
27 | | - |
28 | | -function _build_step([string] $message) { |
29 | | - Write-Host -ForegroundColor White $("==> " + $message + " <==") |
30 | | - Write-Host "" |
31 | | -} |
32 | | - |
33 | | -function _exec([string] $command, [string] $message = "") { |
34 | | - if ($message -eq "") { |
35 | | - $message = $command |
36 | | - } |
37 | | - Write-Host -ForegroundColor DarkGray ("EXEC: " + $message) |
38 | | - Write-Host "" |
39 | | - Invoke-Expression $command |
40 | | - Write-Host "" |
| 7 | +function GuardBin { |
| 8 | + param ( |
| 9 | + [string]$binary, |
| 10 | + [string]$message |
| 11 | + ) |
41 | 12 |
|
42 | | - if ($LASTEXITCODE -ne 0) { |
43 | | - exit 1 |
| 13 | + if ($null -eq (Get-Command $binary -ErrorAction Ignore)) { |
| 14 | + throw "Could not find '$binary'; $message" |
44 | 15 | } |
45 | 16 | } |
46 | 17 |
|
47 | | -function _fatal([string] $message) { |
48 | | - Write-Host -ForegroundColor Red ("Error: " + $message) |
49 | | - exit -1 |
50 | | -} |
51 | | - |
52 | | -function _mkdir([string] $path) { |
53 | | - if ((test-path $path) -eq $false) { |
54 | | - New-Item -Type directory -Path $path | out-null |
55 | | - } |
56 | | -} |
| 18 | +GuardBin git "please install the Git CLI from https://git-scm.com/" |
| 19 | +GuardBin dotnet "please install the .NET SDK from https://dot.net/" |
57 | 20 |
|
58 | | -function _msbuild([string] $project, [string] $configuration, [string] $target = "build", [string] $verbosity = "minimal", [string] $message = "", [string] $binlogFile = "") { |
59 | | - $cmd = "msbuild " + $project + " /t:" + $target + " /p:Configuration=" + $configuration + " /v:" + $verbosity + " /m" |
60 | | - if ($binlogFile -ne "") { |
61 | | - $cmd = $cmd + " /bl:" + $binlogFile |
62 | | - } |
63 | | - _exec $cmd $message |
| 21 | +if ((get-content variable:IsLinux -ErrorAction Ignore) -or (get-content variable:IsMacOS -ErrorAction Ignore)) { |
| 22 | + GuardBin mono "please install Mono from https://www.mono-project.com/" |
| 23 | +} else { |
| 24 | + GuardBin msbuild.exe "please run this from a Visual Studio developer shell" |
64 | 25 | } |
65 | 26 |
|
66 | | -function _require([string] $command, [string] $message) { |
67 | | - if ($null -eq (get-command $command -ErrorAction SilentlyContinue)) { |
68 | | - _fatal $message |
69 | | - } |
| 27 | +$version = [Version]$([regex]::matches((&dotnet --version), '^(\d+\.)?(\d+\.)?(\*|\d+)').value) |
| 28 | +if ($version.Major -lt 8) { |
| 29 | + throw ".NET SDK version ($version) is too low; please install version 8.0 or later from https://dot.net/" |
70 | 30 | } |
71 | 31 |
|
72 | | -function _verify_version([string]$version, [string]$minVersion, [string]$appName) { |
73 | | - $dashIndex = $version.IndexOf('-') |
74 | | - if ($dashIndex -gt -1) { |
75 | | - $version = $version.Substring(0, $dashIndex) |
76 | | - } |
77 | | - |
78 | | - if ([version]$version -lt [version]$minVersion) { |
79 | | - _fatal ("Unsupported " + $appName + " version '$version' (must be '$minVersion' or later).") |
| 32 | +& git submodule status | ForEach-Object { |
| 33 | + if ($_[0] -eq '-') { |
| 34 | + $pieces = $_.Split(' ') |
| 35 | + & git submodule update --init "$($pieces[1])" |
| 36 | + Write-Host "" |
80 | 37 | } |
81 | 38 | } |
82 | 39 |
|
83 | | -function _verify_dotnetsdk_version([string]$minVersion) { |
84 | | - _verify_version (& dotnet --version) $minVersion ".NET SDK" |
85 | | -} |
| 40 | +Push-Location (Split-Path $MyInvocation.MyCommand.Definition) |
86 | 41 |
|
87 | | -function _verify_msbuild_version([string]$minVersion) { |
88 | | - _verify_version (& msbuild /nologo /ver) $minVersion "MSBuild" |
89 | | -} |
90 | | -function _xunit_x64([string]$command) { |
91 | | - _exec ("src\xunit.console\bin\" + $configuration + "\net452\xunit.console.exe " + $command) |
| 42 | +try { |
| 43 | + & dotnet run --project tools/builder --no-launch-profile -- $args |
92 | 44 | } |
93 | | - |
94 | | -function _xunit_x86([string]$command) { |
95 | | - _exec ("src\xunit.console\bin\" + $configuration + "_x86\net452\xunit.console.x86.exe " + $command) |
96 | | -} |
97 | | - |
98 | | -function _xunit_netcore([string]$targetFramework, [string]$command) { |
99 | | - _exec ("dotnet src\xunit.console\bin\" + $configuration + "\" + $targetFramework + "\xunit.console.dll " + $command) |
100 | | -} |
101 | | - |
102 | | -# Top-level targets |
103 | | - |
104 | | -function __target_build() { |
105 | | - __target_restore |
106 | | - __target__analyzesource |
107 | | - |
108 | | - _build_step "Compiling binaries" |
109 | | - _msbuild "xunit.sln" $configuration |
110 | | - _msbuild "src\xunit.console\xunit.console.csproj" ($configuration + "_x86") |
111 | | -} |
112 | | - |
113 | | -function __target_buildall() { |
114 | | - if ($null -ne $env:CI) { |
115 | | - $script:parallelFlags = "-parallel none -maxthreads 1" |
116 | | - $script:nonparallelFlags = "-parallel none -maxthreads 1" |
117 | | - } |
118 | | - |
119 | | - __target_test |
120 | | - __target__publish |
121 | | - __target__packages |
122 | | -} |
123 | | - |
124 | | -function __target_ci() { |
125 | | - __target_buildall |
126 | | - __target__signpackages |
127 | | - __target__pushpackages |
128 | | -} |
129 | | - |
130 | | -function __target_formatsource() { |
131 | | - _build_step "Formatting source" |
132 | | - _exec "& dotnet tool restore" |
133 | | - _exec $dotnetFormatCommand |
| 45 | +finally { |
| 46 | + Pop-Location |
134 | 47 | } |
135 | | - |
136 | | -function __target_packagerestore() { |
137 | | - __target_restore |
138 | | -} |
139 | | - |
140 | | -function __target_packages() { |
141 | | - __target_build |
142 | | - __target__publish |
143 | | - __target__packages |
144 | | -} |
145 | | - |
146 | | -function __target_restore() { |
147 | | - _build_step "Restoring NuGet packages" |
148 | | - _msbuild "xunit.sln" $configuration "restore" |
149 | | -} |
150 | | - |
151 | | -function __target_test() { |
152 | | - __target_build |
153 | | - __target__test32 |
154 | | - __target__test64 |
155 | | - __target__testcore |
156 | | -} |
157 | | - |
158 | | -# Dependent targets |
159 | | - |
160 | | -function __target__analyzesource() { |
161 | | - _build_step "Analyzing source (if this fails, run './build FormatSource' to fix)" |
162 | | - _exec "& dotnet tool restore" |
163 | | - _exec ($dotnetFormatCommand + " --check") |
164 | | -} |
165 | | - |
166 | | -function __target__packages() { |
167 | | - _build_step "Creating NuGet packages" |
168 | | - Get-ChildItem -Path $packageOutputFolder -Recurse -Filter *.nupkg | Remove-Item |
169 | | - Get-ChildItem -Recurse -Filter *.nuspec | ForEach-Object { |
170 | | - _exec ('& dotnet pack --nologo --no-build --configuration ' + $configuration + ' --verbosity minimal --output "' + $packageOutputFolder + '" src/xunit.core -p:NuspecFile="' + $_.FullName + '"') |
171 | | - } |
172 | | -} |
173 | | - |
174 | | -function __target__publish() { |
175 | | - _build_step "Publishing projects for packaging" |
176 | | - _msbuild "src\xunit.console\xunit.console.csproj /p:TargetFramework=netcoreapp1.0" $configuration "publish" |
177 | | - _msbuild "src\xunit.console\xunit.console.csproj /p:TargetFramework=netcoreapp2.0" $configuration "publish" |
178 | | - _msbuild "src\xunit.console\xunit.console.csproj /p:TargetFramework=net6.0" $configuration "publish" |
179 | | -} |
180 | | - |
181 | | -function __target__pushpackages() { |
182 | | - _build_step "Pushing NuGet packages" |
183 | | - if (($null -eq $env:PUSH_APIKEY) -or |
184 | | - ($null -eq $env:PUSH_URI)) |
185 | | - { |
186 | | - Write-Host -ForegroundColor Yellow "Skipping package push because of one or more missing environment variables: 'PUSH_APIKEY', 'PUSH_URI'" |
187 | | - Write-Host "" |
188 | | - } else { |
189 | | - Get-ChildItem -Filter *.nupkg $packageOutputFolder | ForEach-Object { |
190 | | - $cmd = '& dotnet nuget push --source ' + $env:PUSH_URI + ' --api-key ' + $env:PUSH_APIKEY + ' "' + $_.FullName + '"' |
191 | | - $message = $cmd.Replace($env:PUSH_APIKEY, "[redacted]") |
192 | | - _exec $cmd $message |
193 | | - } |
194 | | - } |
195 | | -} |
196 | | - |
197 | | -function __target__signpackages() { |
198 | | - _build_step "Signing NuGet packages" |
199 | | - if (($null -eq $env:SIGN_APP_ID) -or |
200 | | - ($null -eq $env:SIGN_APP_SECRET) -or |
201 | | - ($null -eq $env:SIGN_CERT_NAME) -or |
202 | | - ($null -eq $env:SIGN_TENANT) -or |
203 | | - ($null -eq $env:SIGN_TIMESTAMP_URI) -or |
204 | | - ($null -eq $env:SIGN_VAULT_URI)) |
205 | | - { |
206 | | - Write-Host -ForegroundColor Yellow "Skipping package sign because of one or more missing environment variables: 'SIGN_APP_ID', 'SIGN_APP_SECRET', 'SIGN_CERT_NAME', 'SIGN_TENANT', 'SIGN_TIMESTAMP_URI', 'SIGN_VAULT_URI'" |
207 | | - Write-Host "" |
208 | | - } else { |
209 | | - _exec "& dotnet tool restore" |
210 | | - |
211 | | - $cmd = ` |
212 | | - '& dotnet sign code azure-key-vault **/*.nupkg' + ` |
213 | | - ' --base-directory "' + $packageOutputFolder + '"' + ` |
214 | | - ' --description "xUnit.net"' + ` |
215 | | - ' --description-url https://github.com/xunit' + ` |
216 | | - ' --timestamp-url ' + $env:SIGN_TIMESTAMP_URI + ` |
217 | | - ' --azure-key-vault-url ' + $env:SIGN_VAULT_URI + ` |
218 | | - ' --azure-key-vault-client-id ' + $env:SIGN_APP_ID + ` |
219 | | - ' --azure-key-vault-client-secret "' + $env:SIGN_APP_SECRET + '"' + ` |
220 | | - ' --azure-key-vault-tenant-id ' + $env:SIGN_TENANT + ` |
221 | | - ' --azure-key-vault-certificate ' + $env:SIGN_CERT_NAME |
222 | | - |
223 | | - $msg = $cmd.Replace($env:SIGN_VAULT_URI, '[redacted]') |
224 | | - $msg = $msg.Replace($env:SIGN_APP_ID, '[redacted]') |
225 | | - $msg = $msg.Replace($env:SIGN_APP_SECRET, '[redacted]') |
226 | | - $msg = $msg.Replace($env:SIGN_TENANT, '[redacted]') |
227 | | - $msg = $msg.Replace($env:SIGN_CERT_NAME, '[redacted]') |
228 | | - _exec $cmd $msg |
229 | | - } |
230 | | -} |
231 | | - |
232 | | -function __target__test32() { |
233 | | - _build_step "Running tests: 32-bit .NET 4.x" |
234 | | - $v2_assemblies = [System.String]::Join(" ", (Get-ChildItem -Recurse -Include test.xunit.*.dll | Where-Object { $_.FullName -match "bin\\" + $configuration + "\\net452" } | ForEach-Object { $_.FullName })) |
235 | | - _xunit_x86 ("test\test.xunit1\bin\" + $configuration + "\net40\test.xunit1.dll -xml artifacts\test\v1-x86.xml -html artifacts\test\v1-x86.html " + $nonparallelFlags) |
236 | | - _xunit_x86 ($v2_assemblies + " -xml artifacts\test\v2-x86.xml -html artifacts\test\v2-x86.html -serialize " + $parallelFlags) |
237 | | -} |
238 | | - |
239 | | -function __target__test64() { |
240 | | - _build_step "Running tests: 64-bit .NET 4.x" |
241 | | - $v2_assemblies = [System.String]::Join(" ", (Get-ChildItem -Recurse -Include test.xunit.*.dll | Where-Object { $_.FullName -match "bin\\" + $configuration + "\\net452" } | ForEach-Object { $_.FullName })) |
242 | | - _xunit_x64 ("test\test.xunit1\bin\" + $configuration + "\net40\test.xunit1.dll -xml artifacts\test\v1-x64.xml -html artifacts\test\v1-x64.html " + $nonparallelFlags) |
243 | | - _xunit_x64 ($v2_assemblies + " -xml artifacts\test\v2-x64.xml -html artifacts\test\v2-x64.html -serialize " + $parallelFlags) |
244 | | -} |
245 | | - |
246 | | -function __target__testcore() { |
247 | | - _build_step "Running tests: .NET Core 2.0" |
248 | | - $netcore_assemblies = [System.String]::Join(" ", (Get-ChildItem -Recurse -Include test.xunit.*.dll | Where-Object { $_.FullName -match "bin\\" + $configuration + "\\netcoreapp2.0" } | ForEach-Object { $_.FullName })) |
249 | | - _xunit_netcore "netcoreapp2.0" ($netcore_assemblies + " -xml artifacts\test\v2-netcore.xml -html artifacts\test\v2-netcore.html -serialize " + $nonparallelFlags) |
250 | | - |
251 | | - _build_step "Running tests: .NET 6" |
252 | | - $net6_assemblies = [System.String]::Join(" ", (Get-ChildItem -Recurse -Include test.xunit.*.dll | Where-Object { $_.FullName -match "bin\\" + $configuration + "\\net6.0" } | ForEach-Object { $_.FullName })) |
253 | | - _xunit_netcore "net6.0" ($net6_assemblies + " -xml artifacts\test\v2-net6.xml -html artifacts\test\v2-net6.html -serialize " + $nonparallelFlags) |
254 | | -} |
255 | | - |
256 | | -# Dispatch |
257 | | - |
258 | | -$targetFunction = (Get-ChildItem ("Function:__target_" + $target.ToLowerInvariant()) -ErrorAction SilentlyContinue) |
259 | | -if ($null -eq $targetFunction) { |
260 | | - _fatal "Unknown target '$target'" |
261 | | -} |
262 | | - |
263 | | -_build_step "Performing pre-build verifications" |
264 | | - _require dotnet "Could not find 'dotnet'. Please ensure .NET SDK 8.0 or later is installed." |
265 | | - _verify_dotnetsdk_version "8.0" |
266 | | - _require msbuild.exe "Could not find 'msbuild'. Please ensure MSBUILD.EXE v17.0 is on the path." |
267 | | - _verify_msbuild_version "17.0.0" |
268 | | - |
269 | | -_mkdir $packageOutputFolder |
270 | | -_mkdir $testOutputFolder |
271 | | -& $targetFunction |
0 commit comments