build.ps1 22.6 KB
Newer Older
J
Jared Parsons 已提交
1 2
#
# This script controls the Roslyn build process. This encompasess everything from build, testing to
J
Jonathon Marolf 已提交
3
# publishing of NuGet packages. The intent is to structure it to allow for a simple flow of logic
J
Jared Parsons 已提交
4 5 6 7 8 9 10 11 12
# between the following phases:
#
#   - restore
#   - build
#   - sign
#   - pack
#   - test
#   - publish
#
J
Jonathon Marolf 已提交
13 14 15
# Each of these phases has a separate command which can be executed independently. For instance
# it's fine to call `build.ps1 -build -testDesktop` followed by repeated calls to
# `.\build.ps1 -testDesktop`.
J
Jared Parsons 已提交
16

J
Jared Parsons 已提交
17 18
[CmdletBinding(PositionalBinding=$false)]
param (
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
  [string][Alias('c')]$configuration = "Debug",
  [string][Alias('v')]$verbosity = "m",
  [string]$msbuildEngine = "vs",

  # Actions
  [switch][Alias('r')]$restore,
  [switch][Alias('b')]$build,
  [switch]$rebuild,
  [switch]$sign,
  [switch]$pack,
  [switch]$publish,
  [switch]$launch,
  [switch]$help,

  # Options
  [switch]$bootstrap,
  [string]$bootstrapConfiguration = "Release",
  [switch][Alias('bl')]$binaryLog,
  [switch]$buildServerLog,
  [switch]$ci,
  [switch]$procdump,
  [switch]$skipAnalyzers,
  [switch][Alias('d')]$deployExtensions,
  [switch]$prepareMachine,
  [switch]$useGlobalNuGetCache = $true,
  [switch]$warnAsError = $false,

  # official build settings
  [string]$officialBuildId = "",
  [string]$officialSkipApplyOptimizationData = "",
  [string]$officialSkipTests = "",
  [string]$officialSourceBranchName = "",
  [string]$officialIbcSourceBranchName = "",
  [string]$officialIbcDropId = "",

  # Test actions
  [switch]$test32,
  [switch]$test64,
  [switch]$testVsi,
  [switch][Alias('test')]$testDesktop,
  [switch]$testCoreClr,
  [switch]$testIOperation,
  [switch]$testLegacyCompletion,

  [parameter(ValueFromRemainingArguments=$true)][string[]]$properties)
J
Jared Parsons 已提交
64 65

Set-StrictMode -version 2.0
J
Jared Parsons 已提交
66
$ErrorActionPreference = "Stop"
J
Jared Parsons 已提交
67 68

function Print-Usage() {
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
  Write-Host "Common settings:"
  Write-Host "  -configuration <value>    Build configuration: 'Debug' or 'Release' (short: -c)"
  Write-Host "  -verbosity <value>        Msbuild verbosity: q[uiet], m[inimal], n[ormal], d[etailed], and diag[nostic]"
  Write-Host "  -deployExtensions         Deploy built vsixes (short: -d)"
  Write-Host "  -binaryLog                Create MSBuild binary log (short: -bl)"
  Write-Host "  -buildServerLog           Create Roslyn build server log"
  Write-Host ""
  Write-Host "Actions:"
  Write-Host "  -restore                  Restore packages (short: -r)"
  Write-Host "  -build                    Build main solution (short: -b)"
  Write-Host "  -rebuild                  Rebuild main solution"
  Write-Host "  -pack                     Build NuGet packages, VS insertion manifests and installer"
  Write-Host "  -sign                     Sign our binaries"
  Write-Host "  -publish                  Publish build artifacts (e.g. symbols)"
  Write-Host "  -launch                   Launch Visual Studio in developer hive"
  Write-Host "  -help                     Print help and exit"
  Write-Host ""
  Write-Host "Test actions"
  Write-Host "  -test32                   Run unit tests in the 32-bit runner"
  Write-Host "  -test64                   Run units tests in the 64-bit runner"
  Write-Host "  -testDesktop              Run Desktop unit tests (short: -test)"
  Write-Host "  -testCoreClr              Run CoreClr unit tests"
  Write-Host "  -testVsi                  Run all integration tests"
  Write-Host "  -testIOperation           Run extra checks to validate IOperations"
  Write-Host "  -testLegacyCompletion     Run integration tests with legacy completion"
  Write-Host ""
  Write-Host "Advanced settings:"
  Write-Host "  -ci                       Set when running on CI server"
  Write-Host "  -bootstrap                Build using a bootstrap compilers"
  Write-Host "  -bootstrapConfiguration   Build configuration for bootstrap compiler: 'Debug' or 'Release'"
  Write-Host "  -msbuildEngine <value>    Msbuild engine to use to run build ('dotnet', 'vs', or unspecified)."
  Write-Host "  -procdump                 Monitor test runs with procdump"
  Write-Host "  -skipAnalyzers            Do not run analyzers during build operations"
  Write-Host "  -prepareMachine           Prepare machine for CI run, clean up processes after build"
  Write-Host "  -useGlobalNuGetCache      Use global NuGet cache."
  Write-Host "  -warnAsError              Treat all warnings as errors"
  Write-Host ""
  Write-Host "Official build settings:"
  Write-Host "  -officialBuildId                            An official build id, e.g. 20190102.3"
  Write-Host "  -officialSkipTests <bool>                   Pass 'true' to not run tests"
  Write-Host "  -officialSkipApplyOptimizationData <bool>   Pass 'true' to not apply optimization data"
  Write-Host "  -officialSourceBranchName <string>          The source branch name"
  Write-Host "  -officialIbcDropId <string>                 IBC data drop to use (e.g. '20190210.1/935479/1')."
  Write-Host "                                              'default' for the most recent available for the branch."
  Write-Host "  -officialIbcSourceBranchName <string>       IBC source branch (e.g. 'master-vs-deps')"
  Write-Host "                                              'default' to select branch based on eng/config/PublishData.json."
  Write-Host ""
  Write-Host "Command line arguments starting with '/p:' are passed through to MSBuild."
J
Jared Parsons 已提交
117 118
}

J
Jonathon Marolf 已提交
119
# Process the command line arguments and establish defaults for the values which are not
120 121
# specified.
#
J
Jonathon Marolf 已提交
122
# In this function it's okay to use two arguments to extend the effect of another. For
T
Tomáš Matoušek 已提交
123
# example it's okay to look at $testVsi and infer $skipAnalyzers. It's not okay though to infer
J
Jonathon Marolf 已提交
124
# $build based on say $testDesktop. It's possible the developer wanted only for testing
125
# to execute, not any build.
J
Jared Parsons 已提交
126
function Process-Arguments() {
127 128 129 130 131 132 133 134 135 136 137
  function OfficialBuildOnly([string]$argName) {
    if ((Get-Variable $argName -Scope Script).Value) {
      if (!$officialBuildId) {
        Write-Host "$argName can only be specified for official builds"
        exit 1
      }
    } else {
      if ($officialBuildId) {
        Write-Host "$argName must be specified in official builds"
        exit 1
      }
138
    }
139
  }
140

141
  if ($help -or (($properties -ne $null) -and ($properties.Contains("/help") -or $properties.Contains("/?")))) {
T
Tomáš Matoušek 已提交
142 143
       Print-Usage
       exit 0
144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164
  }

  OfficialBuildOnly "officialSkipTests"
  OfficialBuildOnly "officialSkipApplyOptimizationData"
  OfficialBuildOnly "officialSourceBranchName"
  OfficialBuildOnly "officialIbcDropId"
  OfficialBuildOnly "officialIbcSourceBranchName"

  if ($officialBuildId) {
    $script:useGlobalNuGetCache = $false
    $script:procdump = $true
    $script:testDesktop = ![System.Boolean]::Parse($officialSkipTests)
    $script:applyOptimizationData = ![System.Boolean]::Parse($officialSkipApplyOptimizationData)
  } else {
    $script:applyOptimizationData = $false
  }

  if ($ci) {
    $script:binaryLog = $true
    if ($bootstrap) {
      $script:buildServerLog = $true
T
Tomáš Matoušek 已提交
165
    }
166
  }
167

168 169 170 171
  if ($test32 -and $test64) {
    Write-Host "Cannot combine -test32 and -test64"
    exit 1
  }
J
Jared Parsons 已提交
172

173 174 175 176 177
  $anyUnit = $testDesktop -or $testCoreClr
  if ($anyUnit -and $testVsi) {
    Write-Host "Cannot combine unit and VSI testing"
    exit 1
  }
J
Jared Parsons 已提交
178

179 180 181 182 183
  if ($testVsi) {
    # Avoid spending time in analyzers when requested, and also in the slowest integration test builds
    $script:skipAnalyzers = $true
    $script:bootstrap = $false
  }
184

185 186 187 188
  if ($build -and $launch -and -not $deployExtensions) {
    Write-Host -ForegroundColor Red "Cannot combine -build and -launch without -deployExtensions"
    exit 1
  }
189

190
  $script:test32 = -not $test64
191

192 193 194 195 196
  foreach ($property in $properties) {
    if (!$property.StartsWith("/p:", "InvariantCultureIgnoreCase")) {
      Write-Host "Invalid argument: $property"
      Print-Usage
      exit 1
197
    }
198
  }
J
Jared Parsons 已提交
199 200
}

T
Tomáš Matoušek 已提交
201
function BuildSolution() {
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
  # Roslyn.sln can't be built with dotnet due to WPF and VSIX build task dependencies
  $solution = if ($msbuildEngine -eq 'dotnet') { "Compilers.sln" } else { "Roslyn.sln" }

  Write-Host "$($solution):"

  $bl = if ($binaryLog) { "/bl:" + (Join-Path $LogDir "Build.binlog") } else { "" }

  if ($buildServerLog) {
    ${env:ROSLYNCOMMANDLINELOGFILE} = Join-Path $LogDir "Build.Server.log"
  }

  $projects = Join-Path $RepoRoot $solution
  $enableAnalyzers = !$skipAnalyzers
  $toolsetBuildProj = InitializeToolset

  $testTargetFrameworks = if ($testCoreClr) { "netcoreapp3.0%3Bnetcoreapp2.1" } else { "" }
  
  $ibcSourceBranchName = GetIbcSourceBranchName
  $ibcDropId = if ($officialIbcDropId -ne "default") { $officialIbcDropId } else { "" }

  # Do not set this property to true explicitly, since that would override values set in projects.
  $suppressExtensionDeployment = if (!$deployExtensions) { "/p:DeployExtension=false" } else { "" } 

  # Workaround for some machines in the AzDO pool not allowing long paths (%5c is msbuild escaped backslash)
  $ibcDir = Join-Path $RepoRoot ".o%5c"

  try {
    # Setting /p:TreatWarningsAsErrors=true is a workaround for https://github.com/Microsoft/msbuild/issues/3062.
    # We don't pass /warnaserror to msbuild ($warnAsError is set to $false by default above), but set 
    # /p:TreatWarningsAsErrors=true so that compiler reported warnings, other than IDE0055 are treated as errors. 
    # Warnings reported from other msbuild tasks are not treated as errors for now.
    MSBuild $toolsetBuildProj `
      $bl `
      /p:Configuration=$configuration `
      /p:Projects=$projects `
      /p:RepoRoot=$RepoRoot `
      /p:Restore=$restore `
      /p:Build=$build `
      /p:Test=$testCoreClr `
      /p:Rebuild=$rebuild `
      /p:Pack=$pack `
      /p:Sign=$sign `
      /p:Publish=$publish `
      /p:ContinuousIntegrationBuild=$ci `
      /p:OfficialBuildId=$officialBuildId `
      /p:UseRoslynAnalyzers=$enableAnalyzers `
      /p:BootstrapBuildPath=$bootstrapDir `
      /p:TestTargetFrameworks=$testTargetFrameworks `
      /p:TreatWarningsAsErrors=true `
      /p:VisualStudioIbcSourceBranchName=$ibcSourceBranchName `
      /p:VisualStudioIbcDropId=$ibcDropId `
      /p:EnableNgenOptimization=$applyOptimizationData `
      /p:IbcOptimizationDataDir=$ibcDir `
      $suppressExtensionDeployment `
      @properties
  }
  finally {
    ${env:ROSLYNCOMMANDLINELOGFILE} = $null
  }
J
Jared Parsons 已提交
261 262
}

263 264 265 266

# Get the branch that produced the IBC data this build is going to consume.
# IBC data are only merged in official built, but we want to test some of the logic in CI builds as well.
function GetIbcSourceBranchName() {
267
  if (Test-Path variable:global:_IbcSourceBranchName) {
268
      return $global:_IbcSourceBranchName
269
  }
270

271 272
  function calculate {
    $fallback = "master-vs-deps"
273

274 275 276
    if (!$officialIbcSourceBranchName) {
      return $fallback
    }  
277

278 279 280
    if ($officialIbcSourceBranchName -ne "default") {
      return $officialIbcSourceBranchName
    }
281

282 283 284 285 286 287
    $branchData = GetBranchPublishData $officialSourceBranchName
    if ($branchData -eq $null) {
      Write-Host "Warning: Branch $officialSourceBranchName is not listed in PublishData.json. Using IBC data from '$fallback'." -ForegroundColor Yellow
      Write-Host "Override by setting IbcSourceBranchName build variable." -ForegroundColor Yellow
      return $fallback
    }
288

289 290
    if (Get-Member -InputObject $branchData -Name "ibcSourceBranch") {
      return $branchData.ibcSourceBranch 
291 292
    }

293 294 295 296
    return $officialSourceBranchName
  }

  return $global:_IbcSourceBranchName = calculate
297 298
}

299
# Set VSO variables used by MicroBuildBuildVSBootstrapper pipeline task
300
function SetVisualStudioBootstrapperBuildArgs() {
301
  $fallbackBranch = "master-vs-deps"
302

303 304
  $branchName = if ($officialSourceBranchName) { $officialSourceBranchName } else { $fallbackBranch }
  $branchData = GetBranchPublishData $branchName
305

306 307 308 309
  if ($branchData -eq $null) {
    Write-Host "Warning: Branch $officialSourceBranchName is not listed in PublishData.json. Using VS bootstrapper for branch '$fallbackBranch'. " -ForegroundColor Yellow
    $branchData = GetBranchPublishData $fallbackBranch
  }
310

311 312 313 314
  # VS branch name is e.g. "lab/d16.0stg", "rel/d15.9", "lab/ml", etc.
  $vsBranchSimpleName = $branchData.vsBranch.Split('/')[-1]
  $vsMajorVersion = $branchData.vsMajorVersion
  $vsChannel = "int.$vsBranchSimpleName"
315

316 317
  Write-Host "##vso[task.setvariable variable=VisualStudio.MajorVersion;]$vsMajorVersion"        
  Write-Host "##vso[task.setvariable variable=VisualStudio.ChannelName;]$vsChannel"
318

319 320 321
  $insertionDir = Join-Path $VSSetupDir "Insertion"
  $manifestList = [string]::Join(',', (Get-ChildItem "$insertionDir\*.vsman"))
  Write-Host "##vso[task.setvariable variable=VisualStudio.SetupManifestList;]$manifestList"
322
}
323

J
Jared Parsons 已提交
324
# Core function for running our unit / integration tests tests
T
Tomáš Matoušek 已提交
325
function TestUsingOptimizedRunner() {
326

327 328
  # Tests need to locate .NET Core SDK
  $dotnet = InitializeDotNetCli
329

330 331
  if ($testVsi) {
    Deploy-VsixViaTool
J
Jared Parsons 已提交
332

333 334 335 336
    if ($ci) {
      # Minimize all windows to avoid interference during integration test runs
      $shell = New-Object -ComObject "Shell.Application"
      $shell.MinimizeAll()
337
    }
338
  }
339

340 341 342
  if ($testIOperation) {
    $env:ROSLYN_TEST_IOPERATION = "true"
  }
T
Tomáš Matoušek 已提交
343

344 345 346
  if ($testLegacyCompletion) {
    $env:ROSLYN_TEST_LEGACY_COMPLETION = "true"
  }
T
Tomáš Matoušek 已提交
347

348 349
  $secondaryLogDir = Join-Path (Join-Path $ArtifactsDir "log2") $configuration
  Create-Directory $secondaryLogDir
350 351 352
  $testResultsDir = Join-Path $ArtifactsDir "TestResults\$configuration"
  $binDir = Join-Path $ArtifactsDir "bin" 
  $runTests = GetProjectOutputBinary "RunTests.exe"
353

354 355 356 357 358 359 360 361 362
  if (!(Test-Path $runTests)) {
    Write-Host "Test runner not found: '$runTests'. Run Build.cmd first." -ForegroundColor Red 
    ExitWithExitCode 1
  }

  $xunitDir = Join-Path (Get-PackageDir "xunit.runner.console") "tools\net472"
  $args = "`"$xunitDir`""
  $args += " `"-out:$testResultsDir`""
  $args += " `"-logs:$LogDir`""
363
  $args += " `"-secondaryLogs:$secondaryLogDir`""
364 365 366 367 368 369
  $args += " -nocache"
  $args += " -tfm:net472"

  if ($testDesktop -or $testIOperation) {
    if ($test32) {
      $dlls = Get-ChildItem -Recurse -Include "*.UnitTests.dll" $binDir
T
Tomáš Matoušek 已提交
370
    } else {
371 372 373 374 375 376 377
      $dlls = Get-ChildItem -Recurse -Include "*.UnitTests.dll" -Exclude "*InteractiveHost*" $binDir
    }
  } elseif ($testVsi) {
    # Since they require Visual Studio to be installed, ensure that the MSBuildWorkspace tests run along with our VS
    # integration tests in CI.
    if ($ci) {
      $dlls += @(Get-Item (GetProjectOutputBinary "Microsoft.CodeAnalysis.Workspaces.MSBuild.UnitTests.dll"))
378
    }
379

380
    $dlls += @(Get-ChildItem -Recurse -Include "*.IntegrationTests.dll" $binDir)
381
    $args += " -testVsi"
382 383 384 385
  } else {
    $dlls = Get-ChildItem -Recurse -Include "*.IntegrationTests.dll" $binDir
    $args += " -trait:Feature=NetCore"
  }
J
Jared Parsons 已提交
386

387 388
  # Exclude out the multi-targetted netcore app projects
  $dlls = $dlls | ?{ -not ($_.FullName -match ".*netcoreapp.*") }
389

390 391 392
  # Exclude out the ref assemblies
  $dlls = $dlls | ?{ -not ($_.FullName -match ".*\\ref\\.*") }
  $dlls = $dlls | ?{ -not ($_.FullName -match ".*/ref/.*") }
393

394 395 396 397 398 399
  if ($ci) {
    $args += " -xml"
    if ($testVsi) {
      $args += " -timeout:110"
    } else {
      $args += " -timeout:65"
400
    }
401
  }
402

403 404 405 406 407
  $procdumpPath = Ensure-ProcDump
  $args += " -procdumppath:$procDumpPath"
  if ($procdump) {
    $args += " -useprocdump";
  }
408

409 410 411
  if ($test64) {
    $args += " -test64"
  }
J
Jonathon Marolf 已提交
412

413 414 415 416 417 418 419 420 421 422 423 424 425
  foreach ($dll in $dlls) {
    $args += " $dll"
  }

  try {
    Exec-Console $runTests $args
  } finally {
    Get-Process "xunit*" -ErrorAction SilentlyContinue | Stop-Process
    if ($testIOperation) {
      Remove-Item env:\ROSLYN_TEST_IOPERATION
    }
    if ($testLegacyCompletion) {
      Remove-Item env:\ROSLYN_TEST_LEGACY_COMPLETION
426
    }
427
  }
J
Jared Parsons 已提交
428 429
}

S
Sam Harwell 已提交
430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445
function EnablePreviewSdks() {
  $vsInfo = LocateVisualStudio
  if ($vsInfo -eq $null) {
    # Preview SDKs are allowed when no Visual Studio instance is installed
    return
  }

  $vsId = $vsInfo.instanceId
  $vsMajorVersion = $vsInfo.installationVersion.Split('.')[0]

  $instanceDir = Join-Path ${env:USERPROFILE} "AppData\Local\Microsoft\VisualStudio\$vsMajorVersion.0_$vsId"
  Create-Directory $instanceDir
  $sdkFile = Join-Path $instanceDir "sdk.txt"
  'UsePreviews=True' | Set-Content $sdkFile
}

J
Jonathon Marolf 已提交
446
# Deploy our core VSIX libraries to Visual Studio via the Roslyn VSIX tool.  This is an alternative to
J
Jared Parsons 已提交
447
# deploying at build time.
448
function Deploy-VsixViaTool() { 
449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495
  $vsixDir = Get-PackageDir "RoslynTools.VSIXExpInstaller"
  $vsixExe = Join-Path $vsixDir "tools\VsixExpInstaller.exe"
  
  $vsInfo = LocateVisualStudio
  if ($vsInfo -eq $null) {
    throw "Unable to locate required Visual Studio installation"
  }

  $vsDir = $vsInfo.installationPath.TrimEnd("\")
  $vsId = $vsInfo.instanceId
  $vsMajorVersion = $vsInfo.installationVersion.Split('.')[0]

  $hive = "RoslynDev"
  Write-Host "Using VS Instance $vsId at `"$vsDir`""
  $baseArgs = "/rootSuffix:$hive /vsInstallDir:`"$vsDir`""

  Write-Host "Uninstalling old Roslyn VSIX"

  # Actual uninstall is failing at the moment using the uninstall options. Temporarily using
  # wildfire to uninstall our VSIX extensions
  $extDir = Join-Path ${env:USERPROFILE} "AppData\Local\Microsoft\VisualStudio\$vsMajorVersion.0_$vsid$hive"
  if (Test-Path $extDir) {
    foreach ($dir in Get-ChildItem -Directory $extDir) {
      $name = Split-Path -leaf $dir
      Write-Host "`tUninstalling $name"
    }
    Remove-Item -re -fo $extDir
  }

  Write-Host "Installing all Roslyn VSIX"

  # VSIX files need to be installed in this specific order:
  $orderedVsixFileNames = @(
    "Roslyn.Compilers.Extension.vsix",
    "Roslyn.VisualStudio.Setup.vsix",
    "Roslyn.VisualStudio.Setup.Dependencies.vsix",
    "Roslyn.VisualStudio.InteractiveComponents.vsix",
    "ExpressionEvaluatorPackage.vsix",
    "Roslyn.VisualStudio.DiagnosticsWindow.vsix",
    "Microsoft.VisualStudio.IntegrationTest.Setup.vsix")

  foreach ($vsixFileName in $orderedVsixFileNames) {
    $vsixFile = Join-Path $VSSetupDir $vsixFileName
    $fullArg = "$baseArgs $vsixFile"
    Write-Host "`tInstalling $vsixFileName"
    Exec-Console $vsixExe $fullArg
  }
J
Jared Parsons 已提交
496 497
}

J
Jonathon Marolf 已提交
498
# Ensure that procdump is available on the machine.  Returns the path to the directory that contains
J
Jared Parsons 已提交
499 500 501
# the procdump binaries (both 32 and 64 bit)
function Ensure-ProcDump() {

502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518
  # Jenkins images default to having procdump installed in the root.  Use that if available to avoid
  # an unnecessary download.
  if (Test-Path "C:\SysInternals\procdump.exe") {
    return "C:\SysInternals"
  }

  $outDir = Join-Path $ToolsDir "ProcDump"
  $filePath = Join-Path $outDir "procdump.exe"
  if (-not (Test-Path $filePath)) {
    Remove-Item -Re $filePath -ErrorAction SilentlyContinue
    Create-Directory $outDir
    $zipFilePath = Join-Path $toolsDir "procdump.zip"
    Invoke-WebRequest "https://download.sysinternals.com/files/Procdump.zip" -UseBasicParsing -outfile $zipFilePath | Out-Null
    Unzip $zipFilePath $outDir
  }

  return $outDir
J
Jared Parsons 已提交
519 520
}

J
Jared Parsons 已提交
521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563
# Setup the CI machine for running our integration tests.
function Setup-IntegrationTestRun() {
  $processesToStopOnExit += "devenv"
  $screenshotPath = (Join-Path $LogDir "StartingBuild.png")
  try {
    Capture-Screenshot $screenshotPath
  }
  catch {
    Write-Host "Screenshot failed; attempting to connect to the console"

    # Keep the session open so we have a UI to interact with
    $quserItems = ((quser $env:USERNAME | select -Skip 1) -split '\s+')
    $sessionid = $quserItems[2]
    if ($sessionid -eq 'Disc') {
      # When the session isn't connected, the third value is 'Disc' instead of the ID
      $sessionid = $quserItems[1]
    }

    if ($quserItems[1] -eq 'console') {
      Write-Host "Disconnecting from console before attempting reconnection"
      try {
        tsdiscon
      } catch {
        # ignore
      }

      # Disconnection is asynchronous, so wait a few seconds for it to complete
      Start-Sleep -Seconds 3
      query user
    }

    Write-Host "tscon $sessionid /dest:console"
    tscon $sessionid /dest:console

    # Connection is asynchronous, so wait a few seconds for it to complete
    Start-Sleep 3
    query user

    # Make sure we can capture a screenshot. An exception at this point will fail-fast the build.
    Capture-Screenshot $screenshotPath
  }
}

T
Tomáš Matoušek 已提交
564
function Prepare-TempDir() {
565 566 567 568 569
  Copy-Item (Join-Path $RepoRoot "src\Workspaces\MSBuildTest\Resources\.editorconfig") $TempDir
  Copy-Item (Join-Path $RepoRoot "src\Workspaces\MSBuildTest\Resources\Directory.Build.props") $TempDir
  Copy-Item (Join-Path $RepoRoot "src\Workspaces\MSBuildTest\Resources\Directory.Build.targets") $TempDir
  Copy-Item (Join-Path $RepoRoot "src\Workspaces\MSBuildTest\Resources\Directory.Build.rsp") $TempDir
  Copy-Item (Join-Path $RepoRoot "src\Workspaces\MSBuildTest\Resources\NuGet.Config") $TempDir
J
Jared Parsons 已提交
570
}
J
Fixup  
Jared Parsons 已提交
571

T
Tomáš Matoušek 已提交
572
function List-Processes() {
573 574 575 576 577
  Write-Host "Listing running build processes..."
  Get-Process -Name "msbuild" -ErrorAction SilentlyContinue | Out-Host
  Get-Process -Name "vbcscompiler" -ErrorAction SilentlyContinue | Out-Host
  Get-Process -Name "dotnet" -ErrorAction SilentlyContinue | where { $_.Modules | select { $_.ModuleName -eq "VBCSCompiler.dll" } } | Out-Host
  Get-Process -Name "devenv" -ErrorAction SilentlyContinue | Out-Host
578 579
}

J
Jared Parsons 已提交
580
try {
581 582 583 584
  if ($PSVersionTable.PSVersion.Major -lt "5") {
    Write-Host "PowerShell version must be 5 or greater (version $($PSVersionTable.PSVersion) detected)"
    exit 1
  }
585

586 587
  $regKeyProperty = Get-ItemProperty -Path HKLM:\SYSTEM\CurrentControlSet\Control\FileSystem -Name "LongPathsEnabled" -ErrorAction Ignore
  if (($null -eq $regKeyProperty) -or ($regKeyProperty.LongPathsEnabled -ne 1)) {
J
Jared Parsons 已提交
588
    Write-Host "LongPath is not enabled, you may experience build errors. You can avoid these by enabling LongPath with `"reg ADD HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\FileSystem /v LongPathsEnabled /t REG_DWORD /d 1`""
589
  }
590

591
  Process-Arguments
J
Jared Parsons 已提交
592

593
  . (Join-Path $PSScriptRoot "build-utils.ps1")
594

595
  Push-Location $RepoRoot
T
Tomáš Matoušek 已提交
596

597 598 599
  if ($ci) {
    List-Processes
    Prepare-TempDir
S
Sam Harwell 已提交
600
    EnablePreviewSdks
601
    if ($testVsi) {
J
Jared Parsons 已提交
602
      Setup-IntegrationTestRun 
J
Jared Parsons 已提交
603
    }
604

605 606
    $global:_DotNetInstallDir = Join-Path $RepoRoot ".dotnet"
    InstallDotNetSdk $global:_DotNetInstallDir $GlobalJson.tools.dotnet
607

608 609 610 611
    # Make sure a 2.1 runtime is installed so we can run our tests. Most of them still 
    # target netcoreapp2.1.
    InstallDotNetSdk $global:_DotNetInstallDir "2.1.503"
  }
J
Jared Parsons 已提交
612

613
  if ($bootstrap) {
614
    $bootstrapDir = Make-BootstrapBuild -force32:$test32
615 616 617 618 619 620 621 622 623
  }

  if ($restore -or $build -or $rebuild -or $pack -or $sign -or $publish -or $testCoreClr) {
    BuildSolution
  }

  if ($ci -and $build -and $msbuildEngine -eq "vs") {
    SetVisualStudioBootstrapperBuildArgs
  }
624

625 626 627 628 629 630 631 632 633 634
  if ($testDesktop -or $testVsi -or $testIOperation) {
    TestUsingOptimizedRunner
  }

  if ($launch) {
    $devenvExe = Join-Path $env:VSINSTALLDIR 'Common7\IDE\devenv.exe'
    &$devenvExe /rootSuffix RoslynDev
  }

  ExitWithExitCode 0
J
Jared Parsons 已提交
635 636
}
catch {
637 638 639 640
  Write-Host $_
  Write-Host $_.Exception
  Write-Host $_.ScriptStackTrace
  ExitWithExitCode 1
J
Jared Parsons 已提交
641 642
}
finally {
643 644 645
  if ($ci) {
    Stop-Processes
  }
646
  Pop-Location
J
Jared Parsons 已提交
647
}