From 29a826cee6c8af4b94d75ec5d399c457cfdaac34 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Wed, 5 Jun 2019 12:41:18 +0000 Subject: [PATCH] [master] Update dependencies from dotnet/arcade (#323) * Update dependencies from https://github.com/dotnet/arcade build 20190501.6 - Microsoft.DotNet.Arcade.Sdk - 1.0.0-beta.19251.6 * update core 1.1 version * Update dependencies from https://github.com/dotnet/arcade build 20190502.2 - Microsoft.DotNet.Arcade.Sdk - 1.0.0-beta.19252.2 * Update dependencies from https://github.com/dotnet/arcade build 20190503.8 - Microsoft.DotNet.Arcade.Sdk - 1.0.0-beta.19253.8 * Update dependencies from https://github.com/dotnet/arcade build 20190504.1 - Microsoft.DotNet.Arcade.Sdk - 1.0.0-beta.19254.1 * Update dependencies from https://github.com/dotnet/arcade build 20190505.2 - Microsoft.DotNet.Arcade.Sdk - 1.0.0-beta.19255.2 * Update dependencies from https://github.com/dotnet/arcade build 20190506.12 - Microsoft.DotNet.Arcade.Sdk - 1.0.0-beta.19256.12 * Update dependencies from https://github.com/dotnet/arcade build 20190507.7 - Microsoft.DotNet.Arcade.Sdk - 1.0.0-beta.19257.7 * add additional shared frameworks * try a separate pool * Update dependencies from https://github.com/dotnet/arcade build 20190508.5 - Microsoft.DotNet.Arcade.Sdk - 1.0.0-beta.19258.5 * Update dependencies from https://github.com/dotnet/arcade build 20190509.9 - Microsoft.DotNet.Arcade.Sdk - 1.0.0-beta.19259.9 * Update dependencies from https://github.com/dotnet/arcade build 20190510.2 - Microsoft.DotNet.Arcade.Sdk - 1.0.0-beta.19260.2 * Update dependencies from https://github.com/dotnet/arcade build 20190511.1 - Microsoft.DotNet.Arcade.Sdk - 1.0.0-beta.19261.1 * Update dependencies from https://github.com/dotnet/arcade build 20190512.1 - Microsoft.DotNet.Arcade.Sdk - 1.0.0-beta.19262.1 * Update dependencies from https://github.com/dotnet/arcade build 20190513.3 - Microsoft.DotNet.Arcade.Sdk - 1.0.0-beta.19263.3 * Update dependencies from https://github.com/dotnet/arcade build 20190514.13 - Microsoft.DotNet.Arcade.Sdk - 1.0.0-beta.19264.13 * Update dependencies from https://github.com/dotnet/arcade build 20190516.2 - Microsoft.DotNet.Arcade.Sdk - 1.0.0-beta.19266.2 * Update dependencies from https://github.com/dotnet/arcade build 20190516.4 - Microsoft.DotNet.Arcade.Sdk - 1.0.0-beta.19266.4 * Update dependencies from https://github.com/dotnet/arcade build 20190517.7 - Microsoft.DotNet.Arcade.Sdk - 1.0.0-beta.19267.7 * Update dependencies from https://github.com/dotnet/arcade build 20190518.2 - Microsoft.DotNet.Arcade.Sdk - 1.0.0-beta.19268.2 * Update dependencies from https://github.com/dotnet/arcade build 20190520.1 - Microsoft.DotNet.Arcade.Sdk - 1.0.0-beta.19270.1 * Update dependencies from https://github.com/dotnet/arcade build 20190520.2 - Microsoft.DotNet.Arcade.Sdk - 1.0.0-beta.19270.2 * Update dependencies from https://github.com/dotnet/arcade build 20190521.7 - Microsoft.DotNet.Arcade.Sdk - 1.0.0-beta.19271.7 * Update dependencies from https://github.com/dotnet/arcade build 20190522.13 - Microsoft.DotNet.Arcade.Sdk - 1.0.0-beta.19272.13 * Update dependencies from https://github.com/dotnet/arcade build 20190523.11 - Microsoft.DotNet.Arcade.Sdk - 1.0.0-beta.19273.11 * Update dependencies from https://github.com/dotnet/arcade build 20190524.6 - Microsoft.DotNet.Arcade.Sdk - 1.0.0-beta.19274.6 * Update dependencies from https://github.com/dotnet/arcade build 20190528.1 - Microsoft.DotNet.Arcade.Sdk - 1.0.0-beta.19278.1 * Update dependencies from https://github.com/dotnet/arcade build 20190529.5 - Microsoft.DotNet.Arcade.Sdk - 1.0.0-beta.19279.5 * Update dependencies from https://github.com/dotnet/arcade build 20190530.2 - Microsoft.DotNet.Arcade.Sdk - 1.0.0-beta.19280.2 * Update dependencies from https://github.com/dotnet/arcade build 20190531.5 - Microsoft.DotNet.Arcade.Sdk - 1.0.0-beta.19281.5 * use 2017 pool * install 2.2 sdk * Update dependencies from https://github.com/dotnet/arcade build 20190601.2 - Microsoft.DotNet.Arcade.Sdk - 1.0.0-beta.19301.2 * use new dnceng pool * Update dependencies from https://github.com/dotnet/arcade build 20190602.2 - Microsoft.DotNet.Arcade.Sdk - 1.0.0-beta.19302.2 * Update dependencies from https://github.com/dotnet/arcade build 20190604.1 - Microsoft.DotNet.Arcade.Sdk - 1.0.0-beta.19304.1 --- .vsts-pr.yaml | 15 +- eng/Version.Details.xml | 4 +- eng/common/LoggingCommandFunctions.ps1 | 146 ++++++++++++++++ eng/common/PublishToPackageFeed.proj | 2 + eng/common/build.ps1 | 11 +- eng/common/build.sh | 27 ++- eng/common/cross/arm/sources.list.vivid | 11 -- eng/common/cross/arm/sources.list.wily | 11 -- eng/common/cross/arm64/sources.list.buster | 11 ++ eng/common/cross/arm64/sources.list.stretch | 12 ++ eng/common/cross/arm64/sources.list.vivid | 11 -- eng/common/cross/arm64/sources.list.wily | 11 -- eng/common/cross/build-rootfs.sh | 67 ++++--- eng/common/cross/x86/sources.list.vivid | 11 -- eng/common/cross/x86/sources.list.wily | 11 -- eng/common/darc-init.ps1 | 11 +- eng/common/darc-init.sh | 15 +- eng/common/dotnet-install.cmd | 2 + eng/common/dotnet-install.ps1 | 27 +++ eng/common/dotnet-install.sh | 49 ++++++ eng/common/init-tools-native.ps1 | 6 +- eng/common/init-tools-native.sh | 12 +- eng/common/sdl/NuGet.config | 13 ++ eng/common/sdl/execute-all-sdl-tools.ps1 | 97 +++++++++++ eng/common/sdl/init-sdl.ps1 | 48 +++++ eng/common/sdl/packages.config | 4 + eng/common/sdl/push-gdn.ps1 | 51 ++++++ eng/common/sdl/run-sdl.ps1 | 65 +++++++ eng/common/templates/job/job.yml | 3 + eng/common/templates/steps/send-to-helix.yml | 3 + eng/common/tools.ps1 | 173 +++++++++++++++---- eng/common/tools.sh | 167 ++++++++++++++++-- eng/restore-toolset.ps1 | 5 +- global.json | 4 +- 34 files changed, 935 insertions(+), 181 deletions(-) create mode 100644 eng/common/LoggingCommandFunctions.ps1 delete mode 100644 eng/common/cross/arm/sources.list.vivid delete mode 100644 eng/common/cross/arm/sources.list.wily create mode 100644 eng/common/cross/arm64/sources.list.buster create mode 100644 eng/common/cross/arm64/sources.list.stretch delete mode 100644 eng/common/cross/arm64/sources.list.vivid delete mode 100644 eng/common/cross/arm64/sources.list.wily delete mode 100644 eng/common/cross/x86/sources.list.vivid delete mode 100644 eng/common/cross/x86/sources.list.wily create mode 100644 eng/common/dotnet-install.cmd create mode 100644 eng/common/dotnet-install.ps1 create mode 100644 eng/common/dotnet-install.sh create mode 100644 eng/common/sdl/NuGet.config create mode 100644 eng/common/sdl/execute-all-sdl-tools.ps1 create mode 100644 eng/common/sdl/init-sdl.ps1 create mode 100644 eng/common/sdl/packages.config create mode 100644 eng/common/sdl/push-gdn.ps1 create mode 100644 eng/common/sdl/run-sdl.ps1 diff --git a/.vsts-pr.yaml b/.vsts-pr.yaml index 9fc4ec94e..eddb0e0ef 100644 --- a/.vsts-pr.yaml +++ b/.vsts-pr.yaml @@ -1,9 +1,10 @@ -phases: -- phase: Windows - queue: - name: Hosted VS2017 - timeoutInMinutes: 90 - parallel: 6 +jobs: +- job: Windows + pool: + name: NetCorePublic-Pool + queue: buildpool.windows.10.amd64.vs2019.pre.open + strategy: + maxParallel: 6 matrix: Samples Debug Test: _args: -test @@ -29,6 +30,8 @@ phases: _args: -sign _configuration: Release _solution: Roslyn-SDK + timeoutInMinutes: 90 + steps: - script: eng\PRBuild.cmd $(_args) -configuration $(_configuration) -prepareMachine -projects $(Build.SourcesDirectory)\$(_solution).sln /p:OfficialBuild=false - task: PublishBuildArtifacts@1 diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 8d489b280..cf9c04d6e 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -3,9 +3,9 @@ - + https://github.com/dotnet/arcade - ac8d88df02d246d3147338fcfb03b1b93dc84b53 + d2599acd9703ef747dfb4329ec3e3beff182e755 diff --git a/eng/common/LoggingCommandFunctions.ps1 b/eng/common/LoggingCommandFunctions.ps1 new file mode 100644 index 000000000..c225eaecb --- /dev/null +++ b/eng/common/LoggingCommandFunctions.ps1 @@ -0,0 +1,146 @@ +# Source for this file was taken from https://github.com/microsoft/azure-pipelines-task-lib/blob/11c9439d4af17e6475d9fe058e6b2e03914d17e6/powershell/VstsTaskSdk/LoggingCommandFunctions.ps1 + +# NOTE: You should not be calling these method directly as they are likely to change. Instead you should be calling the Write-Pipeline* functions defined in tools.ps1 + +$script:loggingCommandPrefix = '##vso[' +$script:loggingCommandEscapeMappings = @( # TODO: WHAT ABOUT "="? WHAT ABOUT "%"? + New-Object psobject -Property @{ Token = ';' ; Replacement = '%3B' } + New-Object psobject -Property @{ Token = "`r" ; Replacement = '%0D' } + New-Object psobject -Property @{ Token = "`n" ; Replacement = '%0A' } + New-Object psobject -Property @{ Token = "]" ; Replacement = '%5D' } +) +# TODO: BUG: Escape % ??? +# TODO: Add test to verify don't need to escape "=". + +<######################################## +# Private functions. +########################################> +function Format-LoggingCommandData { + [CmdletBinding()] + param([string]$Value, [switch]$Reverse) + + if (!$Value) { + return '' + } + + if (!$Reverse) { + foreach ($mapping in $script:loggingCommandEscapeMappings) { + $Value = $Value.Replace($mapping.Token, $mapping.Replacement) + } + } else { + for ($i = $script:loggingCommandEscapeMappings.Length - 1 ; $i -ge 0 ; $i--) { + $mapping = $script:loggingCommandEscapeMappings[$i] + $Value = $Value.Replace($mapping.Replacement, $mapping.Token) + } + } + + return $Value +} + +function Format-LoggingCommand { + [CmdletBinding()] + param( + [Parameter(Mandatory = $true)] + [string]$Area, + [Parameter(Mandatory = $true)] + [string]$Event, + [string]$Data, + [hashtable]$Properties) + + # Append the preamble. + [System.Text.StringBuilder]$sb = New-Object -TypeName System.Text.StringBuilder + $null = $sb.Append($script:loggingCommandPrefix).Append($Area).Append('.').Append($Event) + + # Append the properties. + if ($Properties) { + $first = $true + foreach ($key in $Properties.Keys) { + [string]$value = Format-LoggingCommandData $Properties[$key] + if ($value) { + if ($first) { + $null = $sb.Append(' ') + $first = $false + } else { + $null = $sb.Append(';') + } + + $null = $sb.Append("$key=$value") + } + } + } + + # Append the tail and output the value. + $Data = Format-LoggingCommandData $Data + $sb.Append(']').Append($Data).ToString() +} + +function Write-LoggingCommand { + [CmdletBinding(DefaultParameterSetName = 'Parameters')] + param( + [Parameter(Mandatory = $true, ParameterSetName = 'Parameters')] + [string]$Area, + [Parameter(Mandatory = $true, ParameterSetName = 'Parameters')] + [string]$Event, + [Parameter(ParameterSetName = 'Parameters')] + [string]$Data, + [Parameter(ParameterSetName = 'Parameters')] + [hashtable]$Properties, + [Parameter(Mandatory = $true, ParameterSetName = 'Object')] + $Command, + [switch]$AsOutput) + + if ($PSCmdlet.ParameterSetName -eq 'Object') { + Write-LoggingCommand -Area $Command.Area -Event $Command.Event -Data $Command.Data -Properties $Command.Properties -AsOutput:$AsOutput + return + } + + $command = Format-LoggingCommand -Area $Area -Event $Event -Data $Data -Properties $Properties + if ($AsOutput) { + $command + } else { + Write-Host $command + } +} + +function Write-LogIssue { + [CmdletBinding()] + param( + [ValidateSet('warning', 'error')] + [Parameter(Mandatory = $true)] + [string]$Type, + [string]$Message, + [string]$ErrCode, + [string]$SourcePath, + [string]$LineNumber, + [string]$ColumnNumber, + [switch]$AsOutput) + + $command = Format-LoggingCommand -Area 'task' -Event 'logissue' -Data $Message -Properties @{ + 'type' = $Type + 'code' = $ErrCode + 'sourcepath' = $SourcePath + 'linenumber' = $LineNumber + 'columnnumber' = $ColumnNumber + } + if ($AsOutput) { + return $command + } + + if ($Type -eq 'error') { + $foregroundColor = $host.PrivateData.ErrorForegroundColor + $backgroundColor = $host.PrivateData.ErrorBackgroundColor + if ($foregroundColor -isnot [System.ConsoleColor] -or $backgroundColor -isnot [System.ConsoleColor]) { + $foregroundColor = [System.ConsoleColor]::Red + $backgroundColor = [System.ConsoleColor]::Black + } + } else { + $foregroundColor = $host.PrivateData.WarningForegroundColor + $backgroundColor = $host.PrivateData.WarningBackgroundColor + if ($foregroundColor -isnot [System.ConsoleColor] -or $backgroundColor -isnot [System.ConsoleColor]) { + $foregroundColor = [System.ConsoleColor]::Yellow + $backgroundColor = [System.ConsoleColor]::Black + } + } + + Write-Host $command -ForegroundColor $foregroundColor -BackgroundColor $backgroundColor +} \ No newline at end of file diff --git a/eng/common/PublishToPackageFeed.proj b/eng/common/PublishToPackageFeed.proj index e17f72644..a1b133372 100644 --- a/eng/common/PublishToPackageFeed.proj +++ b/eng/common/PublishToPackageFeed.proj @@ -53,6 +53,8 @@ https://dotnetfeed.blob.core.windows.net/dotnet-toolset/index.json https://dotnetfeed.blob.core.windows.net/dotnet-windowsdesktop/index.json https://dotnetfeed.blob.core.windows.net/nuget-nugetclient/index.json + https://dotnetfeed.blob.core.windows.net/aspnet-entityframework6/index.json + https://dotnetfeed.blob.core.windows.net/aspnet-blazor/index.json Build configuration: 'Debug' or 'Release' (short: -c)" + Write-Host " -platform Platform configuration: 'x86', 'x64' or any valid Platform value to pass to msbuild" Write-Host " -verbosity Msbuild verbosity: q[uiet], m[inimal], n[ormal], d[etailed], and diag[nostic] (short: -v)" Write-Host " -binaryLog Output binary log (short: -bl)" Write-Host " -help Print help and exit" @@ -77,6 +79,7 @@ function Build { InitializeCustomToolset $bl = if ($binaryLog) { "/bl:" + (Join-Path $LogDir "Build.binlog") } else { "" } + $platformArg = if ($platform) { "/p:Platform=$platform" } else { "" } if ($projects) { # Re-assign properties to a new variable because PowerShell doesn't let us append properties directly for unclear reasons. @@ -88,6 +91,7 @@ function Build { MSBuild $toolsetBuildProj ` $bl ` + $platformArg ` /p:Configuration=$configuration ` /p:RepoRoot=$RepoRoot ` /p:Restore=$restore ` @@ -122,12 +126,15 @@ try { . $configureToolsetScript } + if (($restore) -and ($null -eq $env:DisableNativeToolsetInstalls)) { + InitializeNativeTools + } + Build } catch { - Write-Host $_ - Write-Host $_.Exception Write-Host $_.ScriptStackTrace + Write-PipelineTaskError -Message $_ ExitWithExitCode 1 } diff --git a/eng/common/build.sh b/eng/common/build.sh index 40b1e8ec7..6236fc4d3 100644 --- a/eng/common/build.sh +++ b/eng/common/build.sh @@ -35,7 +35,7 @@ usage() echo " --nodeReuse Sets nodereuse msbuild parameter ('true' or 'false')" echo " --warnAsError Sets warnaserror msbuild parameter ('true' or 'false')" echo "" - echo "Command line arguments starting with '/p:' are passed through to MSBuild." + echo "Command line arguments not listed above are passed thru to msbuild." echo "Arguments can also be passed in with a single hyphen." } @@ -66,6 +66,7 @@ ci=false warn_as_error=true node_reuse=true binary_log=false +pipelines_log=false projects='' configuration='Debug' @@ -92,6 +93,9 @@ while [[ $# > 0 ]]; do -binarylog|-bl) binary_log=true ;; + -pipelineslog|-pl) + pipelines_log=true + ;; -restore|-r) restore=true ;; @@ -137,22 +141,8 @@ while [[ $# > 0 ]]; do node_reuse=$2 shift ;; - -p:*|/p:*) - properties="$properties $1" - ;; - -m:*|/m:*) - properties="$properties $1" - ;; - -bl:*|/bl:*) - properties="$properties $1" - ;; - -dl:*|/dl:*) - properties="$properties $1" - ;; *) - echo "Invalid argument: $1" - usage - exit 1 + properties="$properties $1" ;; esac @@ -160,6 +150,7 @@ while [[ $# > 0 ]]; do done if [[ "$ci" == true ]]; then + pipelines_log=true binary_log=true node_reuse=false fi @@ -218,4 +209,8 @@ if [[ -n "${useInstalledDotNetCli:-}" ]]; then use_installed_dotnet_cli="$useInstalledDotNetCli" fi +if [[ "$restore" == true && -z ${DisableNativeToolsetInstalls:-} ]]; then + InitializeNativeTools +fi + Build diff --git a/eng/common/cross/arm/sources.list.vivid b/eng/common/cross/arm/sources.list.vivid deleted file mode 100644 index 0b1215e47..000000000 --- a/eng/common/cross/arm/sources.list.vivid +++ /dev/null @@ -1,11 +0,0 @@ -deb http://ports.ubuntu.com/ubuntu-ports/ vivid main restricted universe -deb-src http://ports.ubuntu.com/ubuntu-ports/ vivid main restricted universe - -deb http://ports.ubuntu.com/ubuntu-ports/ vivid-updates main restricted universe -deb-src http://ports.ubuntu.com/ubuntu-ports/ vivid-updates main restricted universe - -deb http://ports.ubuntu.com/ubuntu-ports/ vivid-backports main restricted -deb-src http://ports.ubuntu.com/ubuntu-ports/ vivid-backports main restricted - -deb http://ports.ubuntu.com/ubuntu-ports/ vivid-security main restricted universe multiverse -deb-src http://ports.ubuntu.com/ubuntu-ports/ vivid-security main restricted universe multiverse \ No newline at end of file diff --git a/eng/common/cross/arm/sources.list.wily b/eng/common/cross/arm/sources.list.wily deleted file mode 100644 index e23d1e02a..000000000 --- a/eng/common/cross/arm/sources.list.wily +++ /dev/null @@ -1,11 +0,0 @@ -deb http://ports.ubuntu.com/ubuntu-ports/ wily main restricted universe -deb-src http://ports.ubuntu.com/ubuntu-ports/ wily main restricted universe - -deb http://ports.ubuntu.com/ubuntu-ports/ wily-updates main restricted universe -deb-src http://ports.ubuntu.com/ubuntu-ports/ wily-updates main restricted universe - -deb http://ports.ubuntu.com/ubuntu-ports/ wily-backports main restricted -deb-src http://ports.ubuntu.com/ubuntu-ports/ wily-backports main restricted - -deb http://ports.ubuntu.com/ubuntu-ports/ wily-security main restricted universe multiverse -deb-src http://ports.ubuntu.com/ubuntu-ports/ wily-security main restricted universe multiverse \ No newline at end of file diff --git a/eng/common/cross/arm64/sources.list.buster b/eng/common/cross/arm64/sources.list.buster new file mode 100644 index 000000000..7194ac64a --- /dev/null +++ b/eng/common/cross/arm64/sources.list.buster @@ -0,0 +1,11 @@ +deb http://deb.debian.org/debian buster main +deb-src http://deb.debian.org/debian buster main + +deb http://deb.debian.org/debian-security/ buster/updates main +deb-src http://deb.debian.org/debian-security/ buster/updates main + +deb http://deb.debian.org/debian buster-updates main +deb-src http://deb.debian.org/debian buster-updates main + +deb http://deb.debian.org/debian buster-backports main contrib non-free +deb-src http://deb.debian.org/debian buster-backports main contrib non-free diff --git a/eng/common/cross/arm64/sources.list.stretch b/eng/common/cross/arm64/sources.list.stretch new file mode 100644 index 000000000..0e1215774 --- /dev/null +++ b/eng/common/cross/arm64/sources.list.stretch @@ -0,0 +1,12 @@ +deb http://deb.debian.org/debian stretch main +deb-src http://deb.debian.org/debian stretch main + +deb http://deb.debian.org/debian-security/ stretch/updates main +deb-src http://deb.debian.org/debian-security/ stretch/updates main + +deb http://deb.debian.org/debian stretch-updates main +deb-src http://deb.debian.org/debian stretch-updates main + +deb http://deb.debian.org/debian stretch-backports main contrib non-free +deb-src http://deb.debian.org/debian stretch-backports main contrib non-free + diff --git a/eng/common/cross/arm64/sources.list.vivid b/eng/common/cross/arm64/sources.list.vivid deleted file mode 100644 index 0b1215e47..000000000 --- a/eng/common/cross/arm64/sources.list.vivid +++ /dev/null @@ -1,11 +0,0 @@ -deb http://ports.ubuntu.com/ubuntu-ports/ vivid main restricted universe -deb-src http://ports.ubuntu.com/ubuntu-ports/ vivid main restricted universe - -deb http://ports.ubuntu.com/ubuntu-ports/ vivid-updates main restricted universe -deb-src http://ports.ubuntu.com/ubuntu-ports/ vivid-updates main restricted universe - -deb http://ports.ubuntu.com/ubuntu-ports/ vivid-backports main restricted -deb-src http://ports.ubuntu.com/ubuntu-ports/ vivid-backports main restricted - -deb http://ports.ubuntu.com/ubuntu-ports/ vivid-security main restricted universe multiverse -deb-src http://ports.ubuntu.com/ubuntu-ports/ vivid-security main restricted universe multiverse \ No newline at end of file diff --git a/eng/common/cross/arm64/sources.list.wily b/eng/common/cross/arm64/sources.list.wily deleted file mode 100644 index e23d1e02a..000000000 --- a/eng/common/cross/arm64/sources.list.wily +++ /dev/null @@ -1,11 +0,0 @@ -deb http://ports.ubuntu.com/ubuntu-ports/ wily main restricted universe -deb-src http://ports.ubuntu.com/ubuntu-ports/ wily main restricted universe - -deb http://ports.ubuntu.com/ubuntu-ports/ wily-updates main restricted universe -deb-src http://ports.ubuntu.com/ubuntu-ports/ wily-updates main restricted universe - -deb http://ports.ubuntu.com/ubuntu-ports/ wily-backports main restricted -deb-src http://ports.ubuntu.com/ubuntu-ports/ wily-backports main restricted - -deb http://ports.ubuntu.com/ubuntu-ports/ wily-security main restricted universe multiverse -deb-src http://ports.ubuntu.com/ubuntu-ports/ wily-security main restricted universe multiverse \ No newline at end of file diff --git a/eng/common/cross/build-rootfs.sh b/eng/common/cross/build-rootfs.sh index 805948ca8..34d3d2ba1 100644 --- a/eng/common/cross/build-rootfs.sh +++ b/eng/common/cross/build-rootfs.sh @@ -2,21 +2,21 @@ usage() { - echo "Usage: $0 [BuildArch] [LinuxCodeName] [lldbx.y] [--skipunmount]" + echo "Usage: $0 [BuildArch] [LinuxCodeName] [lldbx.y] [--skipunmount] --rootfsdir ]" echo "BuildArch can be: arm(default), armel, arm64, x86" - echo "LinuxCodeName - optional, Code name for Linux, can be: trusty(default), vivid, wily, xenial, zesty, bionic, alpine. If BuildArch is armel, LinuxCodeName is jessie(default) or tizen." - echo "lldbx.y - optional, LLDB version, can be: lldb3.6(default), lldb3.8, lldb3.9, lldb4.0, no-lldb. Ignored for alpine" + echo "LinuxCodeName - optional, Code name for Linux, can be: trusty, xenial(default), zesty, bionic, alpine. If BuildArch is armel, LinuxCodeName is jessie(default) or tizen." + echo "lldbx.y - optional, LLDB version, can be: lldb3.9(default), lldb4.0, lldb5.0, lldb6.0 no-lldb. Ignored for alpine" echo "--skipunmount - optional, will skip the unmount of rootfs folder." exit 1 } -__LinuxCodeName=trusty +__LinuxCodeName=xenial __CrossDir=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ) __InitialDir=$PWD __BuildArch=arm __UbuntuArch=armhf __UbuntuRepo="http://ports.ubuntu.com/" -__LLDB_Package="lldb-3.6-dev" +__LLDB_Package="liblldb-3.9-dev" __SkipUnmount=0 # base development support @@ -53,8 +53,12 @@ __AlpinePackages+=" openssl-dev" __AlpinePackages+=" zlib-dev" __UnprocessedBuildArgs= -for i in "$@" ; do - lowerI="$(echo $i | awk '{print tolower($0)}')" +while :; do + if [ $# -le 0 ]; then + break + fi + + lowerI="$(echo $1 | awk '{print tolower($0)}')" case $lowerI in -?|-h|--help) usage @@ -95,38 +99,49 @@ for i in "$@" ; do lldb4.0) __LLDB_Package="liblldb-4.0-dev" ;; + lldb5.0) + __LLDB_Package="liblldb-5.0-dev" + ;; + lldb6.0) + __LLDB_Package="liblldb-6.0-dev" + ;; no-lldb) unset __LLDB_Package ;; - vivid) + trusty) # Ubuntu 14.04 if [ "$__LinuxCodeName" != "jessie" ]; then - __LinuxCodeName=vivid + __LinuxCodeName=trusty fi ;; - wily) - if [ "$__LinuxCodeName" != "jessie" ]; then - __LinuxCodeName=wily - fi - ;; - xenial) + xenial) # Ubuntu 16.04 if [ "$__LinuxCodeName" != "jessie" ]; then __LinuxCodeName=xenial fi ;; - zesty) + zesty) # Ubuntu 17.04 if [ "$__LinuxCodeName" != "jessie" ]; then __LinuxCodeName=zesty fi ;; - bionic) + bionic) # Ubuntu 18.04 if [ "$__LinuxCodeName" != "jessie" ]; then __LinuxCodeName=bionic fi ;; - jessie) + jessie) # Debian 8 __LinuxCodeName=jessie __UbuntuRepo="http://ftp.debian.org/debian/" ;; + stretch) # Debian 9 + __LinuxCodeName=stretch + __UbuntuRepo="http://ftp.debian.org/debian/" + __LLDB_Package="liblldb-6.0-dev" + ;; + buster) # Debian 10 + __LinuxCodeName=buster + __UbuntuRepo="http://ftp.debian.org/debian/" + __LLDB_Package="liblldb-6.0-dev" + ;; tizen) if [ "$__BuildArch" != "armel" ]; then echo "Tizen is available only for armel." @@ -144,10 +159,16 @@ for i in "$@" ; do --skipunmount) __SkipUnmount=1 ;; + --rootfsdir|-rootfsdir) + shift + __RootfsDir=$1 + ;; *) - __UnprocessedBuildArgs="$__UnprocessedBuildArgs $i" + __UnprocessedBuildArgs="$__UnprocessedBuildArgs $1" ;; esac + + shift done if [ "$__BuildArch" == "armel" ]; then @@ -155,12 +176,14 @@ if [ "$__BuildArch" == "armel" ]; then fi __UbuntuPackages+=" ${__LLDB_Package:-}" -__RootfsDir="$__CrossDir/rootfs/$__BuildArch" - -if [[ -n "$ROOTFS_DIR" ]]; then +if [ -z "$__RootfsDir" ] && [ ! -z "$ROOTFS_DIR" ]; then __RootfsDir=$ROOTFS_DIR fi +if [ -z "$__RootfsDir" ]; then + __RootfsDir="$__CrossDir/rootfs/$__BuildArch" +fi + if [ -d "$__RootfsDir" ]; then if [ $__SkipUnmount == 0 ]; then umount $__RootfsDir/* diff --git a/eng/common/cross/x86/sources.list.vivid b/eng/common/cross/x86/sources.list.vivid deleted file mode 100644 index 26d37b20f..000000000 --- a/eng/common/cross/x86/sources.list.vivid +++ /dev/null @@ -1,11 +0,0 @@ -deb http://archive.ubuntu.com/ubuntu/ vivid main restricted universe -deb-src http://archive.ubuntu.com/ubuntu/ vivid main restricted universe - -deb http://archive.ubuntu.com/ubuntu/ vivid-updates main restricted universe -deb-src http://archive.ubuntu.com/ubuntu/ vivid-updates main restricted universe - -deb http://archive.ubuntu.com/ubuntu/ vivid-backports main restricted -deb-src http://archive.ubuntu.com/ubuntu/ vivid-backports main restricted - -deb http://archive.ubuntu.com/ubuntu/ vivid-security main restricted universe multiverse -deb-src http://archive.ubuntu.com/ubuntu/ vivid-security main restricted universe multiverse diff --git a/eng/common/cross/x86/sources.list.wily b/eng/common/cross/x86/sources.list.wily deleted file mode 100644 index c4b0b442a..000000000 --- a/eng/common/cross/x86/sources.list.wily +++ /dev/null @@ -1,11 +0,0 @@ -deb http://archive.ubuntu.com/ubuntu/ wily main restricted universe -deb-src http://archive.ubuntu.com/ubuntu/ wily main restricted universe - -deb http://archive.ubuntu.com/ubuntu/ wily-updates main restricted universe -deb-src http://archive.ubuntu.com/ubuntu/ wily-updates main restricted universe - -deb http://archive.ubuntu.com/ubuntu/ wily-backports main restricted -deb-src http://archive.ubuntu.com/ubuntu/ wily-backports main restricted - -deb http://archive.ubuntu.com/ubuntu/ wily-security main restricted universe multiverse -deb-src http://archive.ubuntu.com/ubuntu/ wily-security main restricted universe multiverse diff --git a/eng/common/darc-init.ps1 b/eng/common/darc-init.ps1 index 81ffd1677..dea7cdd90 100644 --- a/eng/common/darc-init.ps1 +++ b/eng/common/darc-init.ps1 @@ -1,5 +1,6 @@ param ( - $darcVersion = $null + $darcVersion = $null, + $versionEndpoint = "https://maestro-prod.westus2.cloudapp.azure.com/api/assets/darc-version?api-version=2019-01-16" ) $verbosity = "m" @@ -16,13 +17,13 @@ function InstallDarcCli ($darcVersion) { Invoke-Expression "& `"$dotnet`" tool uninstall $darcCliPackageName -g" } - # Until we can anonymously query the BAR API for the latest arcade-services - # build applied to the PROD channel, this is hardcoded. + # If the user didn't explicitly specify the darc version, + # query the Maestro API for the correct version of darc to install. if (-not $darcVersion) { - $darcVersion = '1.1.0-beta.19205.4' + $darcVersion = $(Invoke-WebRequest -Uri $versionEndpoint -UseBasicParsing).Content } - $arcadeServicesSource = 'https://dotnetfeed.blob.core.windows.net/dotnet-arcade/index.json' + $arcadeServicesSource = 'https://dotnetfeed.blob.core.windows.net/dotnet-core/index.json' Write-Host "Installing Darc CLI version $darcVersion..." Write-Host "You may need to restart your command window if this is the first dotnet tool you have installed." diff --git a/eng/common/darc-init.sh b/eng/common/darc-init.sh index bd7eb4639..abdd0bc05 100644 --- a/eng/common/darc-init.sh +++ b/eng/common/darc-init.sh @@ -1,7 +1,8 @@ #!/usr/bin/env bash source="${BASH_SOURCE[0]}" -darcVersion="1.1.0-beta.19205.4" +darcVersion='' +versionEndpoint="https://maestro-prod.westus2.cloudapp.azure.com/api/assets/darc-version?api-version=2019-01-16" while [[ $# > 0 ]]; do opt="$(echo "$1" | awk '{print tolower($0)}')" @@ -10,6 +11,10 @@ while [[ $# > 0 ]]; do darcVersion=$2 shift ;; + --versionendpoint) + versionEndpoint=$2 + shift + ;; *) echo "Invalid argument: $1" usage @@ -33,6 +38,10 @@ verbosity=m . "$scriptroot/tools.sh" +if [ -z "$darcVersion" ]; then + darcVersion=$(curl -X GET "$versionEndpoint" -H "accept: text/plain") +fi + function InstallDarcCli { local darc_cli_package_name="microsoft.dotnet.darc" @@ -45,9 +54,9 @@ function InstallDarcCli { echo $($dotnet_root/dotnet tool uninstall $darc_cli_package_name -g) fi - local arcadeServicesSource="https://dotnetfeed.blob.core.windows.net/dotnet-arcade/index.json" + local arcadeServicesSource="https://dotnetfeed.blob.core.windows.net/dotnet-core/index.json" - echo "Installing Darc CLI version $toolset_version..." + echo "Installing Darc CLI version $darcVersion..." echo "You may need to restart your command shell if this is the first dotnet tool you have installed." echo $($dotnet_root/dotnet tool install $darc_cli_package_name --version $darcVersion --add-source "$arcadeServicesSource" -v $verbosity -g) } diff --git a/eng/common/dotnet-install.cmd b/eng/common/dotnet-install.cmd new file mode 100644 index 000000000..b1c2642e7 --- /dev/null +++ b/eng/common/dotnet-install.cmd @@ -0,0 +1,2 @@ +@echo off +powershell -ExecutionPolicy ByPass -NoProfile -command "& """%~dp0dotnet-install.ps1""" %*" \ No newline at end of file diff --git a/eng/common/dotnet-install.ps1 b/eng/common/dotnet-install.ps1 new file mode 100644 index 000000000..0b629b830 --- /dev/null +++ b/eng/common/dotnet-install.ps1 @@ -0,0 +1,27 @@ +[CmdletBinding(PositionalBinding=$false)] +Param( + [string] $verbosity = "minimal", + [string] $architecture = "", + [string] $version = "Latest", + [string] $runtime = "dotnet" +) + +. $PSScriptRoot\tools.ps1 + +$dotnetRoot = Join-Path $RepoRoot ".dotnet" + +$installdir = $dotnetRoot +try { + if ($architecture -and $architecture.Trim() -eq "x86") { + $installdir = Join-Path $installdir "x86" + } + InstallDotNet $installdir $version $architecture $runtime $true +} +catch { + Write-Host $_ + Write-Host $_.Exception + Write-Host $_.ScriptStackTrace + ExitWithExitCode 1 +} + +ExitWithExitCode 0 diff --git a/eng/common/dotnet-install.sh b/eng/common/dotnet-install.sh new file mode 100644 index 000000000..c3072c958 --- /dev/null +++ b/eng/common/dotnet-install.sh @@ -0,0 +1,49 @@ +#!/usr/bin/env bash + +source="${BASH_SOURCE[0]}" +# resolve $source until the file is no longer a symlink +while [[ -h "$source" ]]; do + scriptroot="$( cd -P "$( dirname "$source" )" && pwd )" + source="$(readlink "$source")" + # if $source was a relative symlink, we need to resolve it relative to the path where the + # symlink file was located + [[ $source != /* ]] && source="$scriptroot/$source" +done +scriptroot="$( cd -P "$( dirname "$source" )" && pwd )" + +version='Latest' +architecture='' +runtime='dotnet' +while [[ $# > 0 ]]; do + opt="$(echo "$1" | awk '{print tolower($0)}')" + case "$opt" in + -version|-v) + shift + version="$1" + ;; + -architecture|-a) + shift + architecture="$1" + ;; + -runtime|-r) + shift + runtime="$1" + ;; + *) + echo "Invalid argument: $1" + usage + exit 1 + ;; + esac + shift +done + +. "$scriptroot/tools.sh" +dotnetRoot="$repo_root/.dotnet" +InstallDotNet $dotnetRoot $version "$architecture" $runtime true || { + local exit_code=$? + echo "dotnet-install.sh failed (exit code '$exit_code')." >&2 + ExitWithExitCode $exit_code +} + +ExitWithExitCode 0 diff --git a/eng/common/init-tools-native.ps1 b/eng/common/init-tools-native.ps1 index 495a563a7..a4306bd37 100644 --- a/eng/common/init-tools-native.ps1 +++ b/eng/common/init-tools-native.ps1 @@ -41,9 +41,13 @@ Param ( [switch] $Force = $False, [int] $DownloadRetries = 5, [int] $RetryWaitTimeInSeconds = 30, - [string] $GlobalJsonFile = "$PSScriptRoot\..\..\global.json" + [string] $GlobalJsonFile ) +if (!$GlobalJsonFile) { + $GlobalJsonFile = Join-Path (Get-Item $PSScriptRoot).Parent.Parent.FullName "global.json" +} + Set-StrictMode -version 2.0 $ErrorActionPreference="Stop" diff --git a/eng/common/init-tools-native.sh b/eng/common/init-tools-native.sh index 54b70f678..fc72d1394 100644 --- a/eng/common/init-tools-native.sh +++ b/eng/common/init-tools-native.sh @@ -9,7 +9,7 @@ clean=false force=false download_retries=5 retry_wait_time_seconds=30 -global_json_file="${scriptroot}/../../global.json" +global_json_file="$(dirname "$(dirname "${scriptroot}")")/global.json" declare -A native_assets . $scriptroot/native/common-library.sh @@ -71,6 +71,7 @@ function ReadGlobalJsonNativeTools { local native_tools_list=$(echo $native_tools_section | awk -F"[{}]" '{print $2}') native_tools_list=${native_tools_list//[\" ]/} native_tools_list=${native_tools_list//,/$'\n'} + native_tools_list="$(echo -e "${native_tools_list}" | tr -d '[:space:]')" local old_IFS=$IFS while read -r line; do @@ -116,8 +117,6 @@ else installer_command+=" --clean" fi - echo "Installing $tool version $tool_version" - echo "Executing '$installer_command'" $installer_command if [[ $? != 0 ]]; then @@ -127,19 +126,16 @@ else done fi -if [[ ! -z $clean ]]; then +if [[ $clean = true ]]; then exit 0 fi if [[ -d $install_bin ]]; then echo "Native tools are available from $install_bin" - if [[ !-z BUILD_BUILDNUMBER ]]; then - echo "##vso[task.prependpath]$install_bin" - fi + echo "##vso[task.prependpath]$install_bin" else echo "Native tools install directory does not exist, installation failed" >&2 exit 1 fi exit 0 - diff --git a/eng/common/sdl/NuGet.config b/eng/common/sdl/NuGet.config new file mode 100644 index 000000000..0c5451c11 --- /dev/null +++ b/eng/common/sdl/NuGet.config @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/eng/common/sdl/execute-all-sdl-tools.ps1 b/eng/common/sdl/execute-all-sdl-tools.ps1 new file mode 100644 index 000000000..74080f22d --- /dev/null +++ b/eng/common/sdl/execute-all-sdl-tools.ps1 @@ -0,0 +1,97 @@ +Param( + [string] $GuardianPackageName, # Required: the name of guardian CLI pacakge (not needed if GuardianCliLocation is specified) + [string] $NugetPackageDirectory, # Required: directory where NuGet packages are installed (not needed if GuardianCliLocation is specified) + [string] $GuardianCliLocation, # Optional: Direct location of Guardian CLI executable if GuardianPackageName & NugetPackageDirectory are not specified + [string] $Repository, # Required: the name of the repository (e.g. dotnet/arcade) + [string] $BranchName="master", # Optional: name of branch or version of gdn settings; defaults to master + [string] $SourceDirectory, # Required: the directory where source files are located + [string] $ArtifactsDirectory, # Required: the directory where build artifacts are located + [string] $DncEngAccessToken, # Required: access token for dnceng; should be provided via KeyVault + [string[]] $SourceToolsList, # Optional: list of SDL tools to run on source code + [string[]] $ArtifactToolsList, # Optional: list of SDL tools to run on built artifacts + [bool] $TsaPublish=$False, # Optional: true will publish results to TSA; only set to true after onboarding to TSA; TSA is the automated framework used to upload test results as bugs. + [string] $TsaBranchName=$env:BUILD_SOURCEBRANCHNAME, # Optional: required for TSA publish; defaults to $(Build.SourceBranchName); TSA is the automated framework used to upload test results as bugs. + [string] $TsaRepositoryName, # Optional: TSA repository name; will be generated automatically if not submitted; TSA is the automated framework used to upload test results as bugs. + [string] $BuildNumber=$env:BUILD_BUILDNUMBER, # Optional: required for TSA publish; defaults to $(Build.BuildNumber) + [bool] $UpdateBaseline=$False, # Optional: if true, will update the baseline in the repository; should only be run after fixing any issues which need to be fixed + [bool] $TsaOnboard=$False, # Optional: if true, will onboard the repository to TSA; should only be run once; TSA is the automated framework used to upload test results as bugs. + [string] $TsaInstanceUrl, # Optional: only needed if TsaOnboard or TsaPublish is true; the instance-url registered with TSA; TSA is the automated framework used to upload test results as bugs. + [string] $TsaCodebaseName, # Optional: only needed if TsaOnboard or TsaPublish is true; the name of the codebase registered with TSA; TSA is the automated framework used to upload test results as bugs. + [string] $TsaProjectName, # Optional: only needed if TsaOnboard or TsaPublish is true; the name of the project registered with TSA; TSA is the automated framework used to upload test results as bugs. + [string] $TsaNotificationEmail, # Optional: only needed if TsaOnboard is true; the email(s) which will receive notifications of TSA bug filings (e.g. alias@microsoft.com); TSA is the automated framework used to upload test results as bugs. + [string] $TsaCodebaseAdmin, # Optional: only needed if TsaOnboard is true; the aliases which are admins of the TSA codebase (e.g. DOMAIN\alias); TSA is the automated framework used to upload test results as bugs. + [string] $TsaBugAreaPath, # Optional: only needed if TsaOnboard is true; the area path where TSA will file bugs in AzDO; TSA is the automated framework used to upload test results as bugs. + [string] $TsaIterationPath, # Optional: only needed if TsaOnboard is true; the iteration path where TSA will file bugs in AzDO; TSA is the automated framework used to upload test results as bugs. + [string] $GuardianLoggerLevel="Standard" # Optional: the logger level for the Guardian CLI; options are Trace, Verbose, Standard, Warning, and Error +) + +$ErrorActionPreference = "Stop" +Set-StrictMode -Version 2.0 +$LASTEXITCODE = 0 + +#Replace repo names to the format of org/repo +if (!($Repository.contains('/'))) { + $RepoName = $Repository -replace '(.*?)-(.*)', '$1/$2'; +} +else{ + $RepoName = $Repository; +} + +if ($GuardianPackageName) { + $guardianCliLocation = Join-Path $NugetPackageDirectory (Join-Path $GuardianPackageName (Join-Path "tools" "guardian.cmd")) +} else { + $guardianCliLocation = $GuardianCliLocation +} + +$ValidPath = Test-Path $guardianCliLocation + +if ($ValidPath -eq $False) +{ + Write-Host "Invalid Guardian CLI Location." + exit 1 +} + +& $(Join-Path $PSScriptRoot "init-sdl.ps1") -GuardianCliLocation $guardianCliLocation -Repository $RepoName -BranchName $BranchName -WorkingDirectory $ArtifactsDirectory -DncEngAccessToken $DncEngAccessToken -GuardianLoggerLevel $GuardianLoggerLevel +$gdnFolder = Join-Path $ArtifactsDirectory ".gdn" + +if ($TsaOnboard) { + if ($TsaCodebaseName -and $TsaNotificationEmail -and $TsaCodebaseAdmin -and $TsaBugAreaPath) { + Write-Host "$guardianCliLocation tsa-onboard --codebase-name `"$TsaCodebaseName`" --notification-alias `"$TsaNotificationEmail`" --codebase-admin `"$TsaCodebaseAdmin`" --instance-url `"$TsaInstanceUrl`" --project-name `"$TsaProjectName`" --area-path `"$TsaBugAreaPath`" --iteration-path `"$TsaIterationPath`" --working-directory $ArtifactsDirectory --logger-level $GuardianLoggerLevel" + & $guardianCliLocation tsa-onboard --codebase-name "$TsaCodebaseName" --notification-alias "$TsaNotificationEmail" --codebase-admin "$TsaCodebaseAdmin" --instance-url "$TsaInstanceUrl" --project-name "$TsaProjectName" --area-path "$TsaBugAreaPath" --iteration-path "$TsaIterationPath" --working-directory $ArtifactsDirectory --logger-level $GuardianLoggerLevel + if ($LASTEXITCODE -ne 0) { + Write-Host "Guardian tsa-onboard failed with exit code $LASTEXITCODE." + exit $LASTEXITCODE + } + } else { + Write-Host "Could not onboard to TSA -- not all required values ($$TsaCodebaseName, $$TsaNotificationEmail, $$TsaCodebaseAdmin, $$TsaBugAreaPath) were specified." + exit 1 + } +} + +if ($ArtifactToolsList -and $ArtifactToolsList.Count -gt 0) { + & $(Join-Path $PSScriptRoot "run-sdl.ps1") -GuardianCliLocation $guardianCliLocation -WorkingDirectory $ArtifactsDirectory -TargetDirectory $ArtifactsDirectory -GdnFolder $gdnFolder -ToolsList $ArtifactToolsList -DncEngAccessToken $DncEngAccessToken -UpdateBaseline $UpdateBaseline -GuardianLoggerLevel $GuardianLoggerLevel +} +if ($SourceToolsList -and $SourceToolsList.Count -gt 0) { + & $(Join-Path $PSScriptRoot "run-sdl.ps1") -GuardianCliLocation $guardianCliLocation -WorkingDirectory $ArtifactsDirectory -TargetDirectory $SourceDirectory -GdnFolder $gdnFolder -ToolsList $SourceToolsList -DncEngAccessToken $DncEngAccessToken -UpdateBaseline $UpdateBaseline -GuardianLoggerLevel $GuardianLoggerLevel +} + +if ($UpdateBaseline) { + & (Join-Path $PSScriptRoot "push-gdn.ps1") -Repository $RepoName -BranchName $BranchName -GdnFolder $GdnFolder -DncEngAccessToken $DncEngAccessToken -PushReason "Update baseline" +} + +if ($TsaPublish) { + if ($TsaBranchName -and $BuildNumber) { + if (-not $TsaRepositoryName) { + $TsaRepositoryName = "$($Repository)-$($BranchName)" + } + Write-Host "$guardianCliLocation tsa-publish --all-tools --repository-name `"$TsaRepositoryName`" --branch-name `"$TsaBranchName`" --build-number `"$BuildNumber`" --codebase-name `"$TsaCodebaseName`" --notification-alias `"$TsaNotificationEmail`" --codebase-admin `"$TsaCodebaseAdmin`" --instance-url `"$TsaInstanceUrl`" --project-name `"$TsaProjectName`" --area-path `"$TsaBugAreaPath`" --iteration-path `"$TsaIterationPath`" --working-directory $SourceDirectory --logger-level $GuardianLoggerLevel" + & $guardianCliLocation tsa-publish --all-tools --repository-name "$TsaRepositoryName" --branch-name "$TsaBranchName" --build-number "$BuildNumber" --codebase-name "$TsaCodebaseName" --notification-alias "$TsaNotificationEmail" --codebase-admin "$TsaCodebaseAdmin" --instance-url "$TsaInstanceUrl" --project-name "$TsaProjectName" --area-path "$TsaBugAreaPath" --iteration-path "$TsaIterationPath" --working-directory $ArtifactsDirectory --logger-level $GuardianLoggerLevel + if ($LASTEXITCODE -ne 0) { + Write-Host "Guardian tsa-publish failed with exit code $LASTEXITCODE." + exit $LASTEXITCODE + } + } else { + Write-Host "Could not publish to TSA -- not all required values ($$TsaBranchName, $$BuildNumber) were specified." + exit 1 + } +} diff --git a/eng/common/sdl/init-sdl.ps1 b/eng/common/sdl/init-sdl.ps1 new file mode 100644 index 000000000..cbf5c36a8 --- /dev/null +++ b/eng/common/sdl/init-sdl.ps1 @@ -0,0 +1,48 @@ +Param( + [string] $GuardianCliLocation, + [string] $Repository, + [string] $BranchName="master", + [string] $WorkingDirectory, + [string] $DncEngAccessToken, + [string] $GuardianLoggerLevel="Standard" +) + +$ErrorActionPreference = "Stop" +Set-StrictMode -Version 2.0 +$LASTEXITCODE = 0 + +# Construct basic auth from AzDO access token; construct URI to the repository's gdn folder stored in that repository; construct location of zip file +$encodedPat = [Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes(":$DncEngAccessToken")) +$escapedRepository = [Uri]::EscapeDataString("/$Repository/$BranchName/.gdn") +$uri = "https://dev.azure.com/dnceng/internal/_apis/git/repositories/sdl-tool-cfg/Items?path=$escapedRepository&versionDescriptor[versionOptions]=0&`$format=zip&api-version=5.0-preview.1" +$zipFile = "$WorkingDirectory/gdn.zip" + +Add-Type -AssemblyName System.IO.Compression.FileSystem +$gdnFolder = (Join-Path $WorkingDirectory ".gdn") +Try +{ + # We try to download the zip; if the request fails (e.g. the file doesn't exist), we catch it and init guardian instead + Write-Host "Downloading gdn folder from internal config repostiory..." + Invoke-WebRequest -Headers @{ "Accept"="application/zip"; "Authorization"="Basic $encodedPat" } -Uri $uri -OutFile $zipFile + if (Test-Path $gdnFolder) { + # Remove the gdn folder if it exists (it shouldn't unless there's too much caching; this is just in case) + Remove-Item -Force -Recurse $gdnFolder + } + [System.IO.Compression.ZipFile]::ExtractToDirectory($zipFile, $WorkingDirectory) + Write-Host $gdnFolder +} Catch [System.Net.WebException] { + # if the folder does not exist, we'll do a guardian init and push it to the remote repository + Write-Host "Initializing Guardian..." + Write-Host "$GuardianCliLocation init --working-directory $WorkingDirectory --logger-level $GuardianLoggerLevel" + & $GuardianCliLocation init --working-directory $WorkingDirectory --logger-level $GuardianLoggerLevel + if ($LASTEXITCODE -ne 0) { + Write-Error "Guardian init failed with exit code $LASTEXITCODE." + } + # We create the mainbaseline so it can be edited later + Write-Host "$GuardianCliLocation baseline --working-directory $WorkingDirectory --name mainbaseline" + & $GuardianCliLocation baseline --working-directory $WorkingDirectory --name mainbaseline + if ($LASTEXITCODE -ne 0) { + Write-Error "Guardian baseline failed with exit code $LASTEXITCODE." + } + & $(Join-Path $PSScriptRoot "push-gdn.ps1") -Repository $Repository -BranchName $BranchName -GdnFolder $gdnFolder -DncEngAccessToken $DncEngAccessToken -PushReason "Initialize gdn folder" +} \ No newline at end of file diff --git a/eng/common/sdl/packages.config b/eng/common/sdl/packages.config new file mode 100644 index 000000000..b054737df --- /dev/null +++ b/eng/common/sdl/packages.config @@ -0,0 +1,4 @@ + + + + diff --git a/eng/common/sdl/push-gdn.ps1 b/eng/common/sdl/push-gdn.ps1 new file mode 100644 index 000000000..cacaf8e91 --- /dev/null +++ b/eng/common/sdl/push-gdn.ps1 @@ -0,0 +1,51 @@ +Param( + [string] $Repository, + [string] $BranchName="master", + [string] $GdnFolder, + [string] $DncEngAccessToken, + [string] $PushReason +) + +$ErrorActionPreference = "Stop" +Set-StrictMode -Version 2.0 +$LASTEXITCODE = 0 + +# We create the temp directory where we'll store the sdl-config repository +$sdlDir = Join-Path $env:TEMP "sdl" +if (Test-Path $sdlDir) { + Remove-Item -Force -Recurse $sdlDir +} + +Write-Host "git clone https://dnceng:`$DncEngAccessToken@dev.azure.com/dnceng/internal/_git/sdl-tool-cfg $sdlDir" +git clone https://dnceng:$DncEngAccessToken@dev.azure.com/dnceng/internal/_git/sdl-tool-cfg $sdlDir +if ($LASTEXITCODE -ne 0) { + Write-Error "Git clone failed with exit code $LASTEXITCODE." +} +# We copy the .gdn folder from our local run into the git repository so it can be committed +$sdlRepositoryFolder = Join-Path (Join-Path (Join-Path $sdlDir $Repository) $BranchName) ".gdn" +if (Get-Command Robocopy) { + Robocopy /S $GdnFolder $sdlRepositoryFolder +} else { + rsync -r $GdnFolder $sdlRepositoryFolder +} +# cd to the sdl-config directory so we can run git there +Push-Location $sdlDir +# git add . --> git commit --> git push +Write-Host "git add ." +git add . +if ($LASTEXITCODE -ne 0) { + Write-Error "Git add failed with exit code $LASTEXITCODE." +} +Write-Host "git -c user.email=`"dn-bot@microsoft.com`" -c user.name=`"Dotnet Bot`" commit -m `"$PushReason for $Repository/$BranchName`"" +git -c user.email="dn-bot@microsoft.com" -c user.name="Dotnet Bot" commit -m "$PushReason for $Repository/$BranchName" +if ($LASTEXITCODE -ne 0) { + Write-Error "Git commit failed with exit code $LASTEXITCODE." +} +Write-Host "git push" +git push +if ($LASTEXITCODE -ne 0) { + Write-Error "Git push failed with exit code $LASTEXITCODE." +} + +# Return to the original directory +Pop-Location \ No newline at end of file diff --git a/eng/common/sdl/run-sdl.ps1 b/eng/common/sdl/run-sdl.ps1 new file mode 100644 index 000000000..e6a86d03a --- /dev/null +++ b/eng/common/sdl/run-sdl.ps1 @@ -0,0 +1,65 @@ +Param( + [string] $GuardianCliLocation, + [string] $WorkingDirectory, + [string] $TargetDirectory, + [string] $GdnFolder, + [string[]] $ToolsList, + [string] $UpdateBaseline, + [string] $GuardianLoggerLevel="Standard" +) + +$ErrorActionPreference = "Stop" +Set-StrictMode -Version 2.0 +$LASTEXITCODE = 0 + +# We store config files in the r directory of .gdn +Write-Host $ToolsList +$gdnConfigPath = Join-Path $GdnFolder "r" +$ValidPath = Test-Path $GuardianCliLocation + +if ($ValidPath -eq $False) +{ + Write-Host "Invalid Guardian CLI Location." + exit 1 +} + +foreach ($tool in $ToolsList) { + $gdnConfigFile = Join-Path $gdnConfigPath "$tool-configure.gdnconfig" + $config = $False + Write-Host $tool + # We have to manually configure tools that run on source to look at the source directory only + if ($tool -eq "credscan") { + Write-Host "$GuardianCliLocation configure --working-directory $WorkingDirectory --tool $tool --output-path $gdnConfigFile --logger-level $GuardianLoggerLevel --noninteractive --force --args `" TargetDirectory : $TargetDirectory `"" + & $GuardianCliLocation configure --working-directory $WorkingDirectory --tool $tool --output-path $gdnConfigFile --logger-level $GuardianLoggerLevel --noninteractive --force --args " TargetDirectory : $TargetDirectory " + if ($LASTEXITCODE -ne 0) { + Write-Host "Guardian configure for $tool failed with exit code $LASTEXITCODE." + exit $LASTEXITCODE + } + $config = $True + } + if ($tool -eq "policheck") { + Write-Host "$GuardianCliLocation configure --working-directory $WorkingDirectory --tool $tool --output-path $gdnConfigFile --logger-level $GuardianLoggerLevel --noninteractive --force --args `" Target : $TargetDirectory `"" + & $GuardianCliLocation configure --working-directory $WorkingDirectory --tool $tool --output-path $gdnConfigFile --logger-level $GuardianLoggerLevel --noninteractive --force --args " Target : $TargetDirectory " + if ($LASTEXITCODE -ne 0) { + Write-Host "Guardian configure for $tool failed with exit code $LASTEXITCODE." + exit $LASTEXITCODE + } + $config = $True + } + + Write-Host "$GuardianCliLocation run --working-directory $WorkingDirectory --tool $tool --baseline mainbaseline --update-baseline $UpdateBaseline --logger-level $GuardianLoggerLevel --config $gdnConfigFile $config" + if ($config) { + & $GuardianCliLocation run --working-directory $WorkingDirectory --tool $tool --baseline mainbaseline --update-baseline $UpdateBaseline --logger-level $GuardianLoggerLevel --config $gdnConfigFile + if ($LASTEXITCODE -ne 0) { + Write-Host "Guardian run for $tool using $gdnConfigFile failed with exit code $LASTEXITCODE." + exit $LASTEXITCODE + } + } else { + & $GuardianCliLocation run --working-directory $WorkingDirectory --tool $tool --baseline mainbaseline --update-baseline $UpdateBaseline --logger-level $GuardianLoggerLevel + if ($LASTEXITCODE -ne 0) { + Write-Host "Guardian run for $tool failed with exit code $LASTEXITCODE." + exit $LASTEXITCODE + } + } +} + diff --git a/eng/common/templates/job/job.yml b/eng/common/templates/job/job.yml index 7839b70bb..1814e0ab6 100644 --- a/eng/common/templates/job/job.yml +++ b/eng/common/templates/job/job.yml @@ -90,6 +90,9 @@ jobs: timeoutInMinutes: ${{ parameters.timeoutInMinutes }} variables: + - ${{ if eq(parameters.enableTelemetry, 'true') }}: + - name: DOTNET_CLI_TELEMETRY_PROFILE + value: '$(Build.Repository.Uri)' - ${{ each variable in parameters.variables }}: # handle name-value variable syntax # example: diff --git a/eng/common/templates/steps/send-to-helix.yml b/eng/common/templates/steps/send-to-helix.yml index d1ce577db..05df886f5 100644 --- a/eng/common/templates/steps/send-to-helix.yml +++ b/eng/common/templates/steps/send-to-helix.yml @@ -5,6 +5,7 @@ parameters: HelixBuild: $(Build.BuildNumber) # required -- the build number Helix will use to identify this -- automatically set to the AzDO build number HelixTargetQueues: '' # required -- semicolon delimited list of Helix queues to test on; see https://helix.dot.net/ for a list of queues HelixAccessToken: '' # required -- access token to make Helix API requests; should be provided by the appropriate variable group + HelixConfiguration: '' # optional -- additional property attached to a job HelixPreCommands: '' # optional -- commands to run before Helix work item execution HelixPostCommands: '' # optional -- commands to run after Helix work item execution WorkItemDirectory: '' # optional -- a payload directory to zip up and send to Helix; requires WorkItemCommand; incompatible with XUnitProjects @@ -35,6 +36,7 @@ steps: HelixSource: ${{ parameters.HelixSource }} HelixType: ${{ parameters.HelixType }} HelixBuild: ${{ parameters.HelixBuild }} + HelixConfiguration: ${{ parameters.HelixConfiguration }} HelixTargetQueues: ${{ parameters.HelixTargetQueues }} HelixAccessToken: ${{ parameters.HelixAccessToken }} HelixPreCommands: ${{ parameters.HelixPreCommands }} @@ -64,6 +66,7 @@ steps: HelixSource: ${{ parameters.HelixSource }} HelixType: ${{ parameters.HelixType }} HelixBuild: ${{ parameters.HelixBuild }} + HelixConfiguration: ${{ parameters.HelixConfiguration }} HelixTargetQueues: ${{ parameters.HelixTargetQueues }} HelixAccessToken: ${{ parameters.HelixAccessToken }} HelixPreCommands: ${{ parameters.HelixPreCommands }} diff --git a/eng/common/tools.ps1 b/eng/common/tools.ps1 index 5c4a129c8..3983d719b 100644 --- a/eng/common/tools.ps1 +++ b/eng/common/tools.ps1 @@ -11,6 +11,12 @@ # Binary log must be enabled on CI. [bool]$binaryLog = if (Test-Path variable:binaryLog) { $binaryLog } else { $ci } +# Set to true to use the pipelines logger which will enable Azure logging output. +# https://github.com/Microsoft/azure-pipelines-tasks/blob/master/docs/authoring/commands.md +# This flag is meant as a temporary opt-opt for the feature while validate it across +# our consumers. It will be deleted in the future. +[bool]$pipelinesLog = if (Test-Path variable:pipelinesLog) { $pipelinesLog } else { $ci } + # Turns on machine preparation/clean up code that changes the machine state (e.g. kills build processes). [bool]$prepareMachine = if (Test-Path variable:prepareMachine) { $prepareMachine } else { $false } @@ -86,6 +92,68 @@ function Exec-Process([string]$command, [string]$commandArgs) { } } +function Write-PipelineTaskError { + [CmdletBinding()] + param( + [Parameter(Mandatory = $true)] + [string]$Message, + [Parameter(Mandatory = $false)] + [string]$Type = 'error', + [string]$ErrCode, + [string]$SourcePath, + [string]$LineNumber, + [string]$ColumnNumber, + [switch]$AsOutput) + + if(!$ci) { + if($Type -eq 'error') { + Write-Error $Message + return + } + elseif ($Type -eq 'warning') { + Write-Warning $Message + return + } + } + + if(($Type -ne 'error') -and ($Type -ne 'warning')) { + Write-Host $Message + return + } + if(-not $PSBoundParameters.ContainsKey('Type')) { + $PSBoundParameters.Add('Type', 'error') + } + Write-LogIssue @PSBoundParameters +} + +function Write-PipelineSetVariable { + [CmdletBinding()] + param( + [Parameter(Mandatory = $true)] + [string]$Name, + [string]$Value, + [switch]$Secret, + [switch]$AsOutput) + + if($ci) { + Write-LoggingCommand -Area 'task' -Event 'setvariable' -Data $Value -Properties @{ + 'variable' = $Name + 'issecret' = $Secret + } -AsOutput:$AsOutput + } +} + +function Write-PipelinePrependPath { + [CmdletBinding()] + param( + [Parameter(Mandatory=$true)] + [string]$Path, + [switch]$AsOutput) + if($ci) { + Write-LoggingCommand -Area 'task' -Event 'prependpath' -Data $Path -AsOutput:$AsOutput + } +} + function InitializeDotNetCli([bool]$install) { if (Test-Path variable:global:_DotNetInstallDir) { return $global:_DotNetInstallDir @@ -108,7 +176,7 @@ function InitializeDotNetCli([bool]$install) { } # Find the first path on %PATH% that contains the dotnet.exe - if ($useInstalledDotNetCli -and ($env:DOTNET_INSTALL_DIR -eq $null)) { + if ($useInstalledDotNetCli -and (-not $globalJsonHasRuntimes) -and ($env:DOTNET_INSTALL_DIR -eq $null)) { $dotnetCmd = Get-Command "dotnet.exe" -ErrorAction SilentlyContinue if ($dotnetCmd -ne $null) { $env:DOTNET_INSTALL_DIR = Split-Path $dotnetCmd.Path -Parent @@ -119,7 +187,7 @@ function InitializeDotNetCli([bool]$install) { # Use dotnet installation specified in DOTNET_INSTALL_DIR if it contains the required SDK version, # otherwise install the dotnet CLI and SDK to repo local .dotnet directory to avoid potential permission issues. - if (($env:DOTNET_INSTALL_DIR -ne $null) -and (Test-Path(Join-Path $env:DOTNET_INSTALL_DIR "sdk\$dotnetSdkVersion"))) { + if ((-not $globalJsonHasRuntimes) -and ($env:DOTNET_INSTALL_DIR -ne $null) -and (Test-Path(Join-Path $env:DOTNET_INSTALL_DIR "sdk\$dotnetSdkVersion"))) { $dotnetRoot = $env:DOTNET_INSTALL_DIR } else { $dotnetRoot = Join-Path $RepoRoot ".dotnet" @@ -128,7 +196,7 @@ function InitializeDotNetCli([bool]$install) { if ($install) { InstallDotNetSdk $dotnetRoot $dotnetSdkVersion } else { - Write-Host "Unable to find dotnet with SDK version '$dotnetSdkVersion'" -ForegroundColor Red + Write-PipelineTaskError "Unable to find dotnet with SDK version '$dotnetSdkVersion'" ExitWithExitCode 1 } } @@ -141,18 +209,16 @@ function InitializeDotNetCli([bool]$install) { # It also ensures that VS msbuild will use the downloaded sdk targets. $env:PATH = "$dotnetRoot;$env:PATH" - if ($ci) { - # Make Sure that our bootstrapped dotnet cli is avaliable in future steps of the Azure Pipelines build - Write-Host "##vso[task.prependpath]$dotnetRoot" - Write-Host "##vso[task.setvariable variable=DOTNET_MULTILEVEL_LOOKUP]0" - Write-Host "##vso[task.setvariable variable=DOTNET_SKIP_FIRST_TIME_EXPERIENCE]1" - } + # Make Sure that our bootstrapped dotnet cli is avaliable in future steps of the Azure Pipelines build + Write-PipelinePrependPath -Path $dotnetRoot + Write-PipelineSetVariable -Name 'DOTNET_MULTILEVEL_LOOKUP' -Value '0' + Write-PipelineSetVariable -Name 'DOTNET_SKIP_FIRST_TIME_EXPERIENCE' -Value '1' return $global:_DotNetInstallDir = $dotnetRoot } function GetDotNetInstallScript([string] $dotnetRoot) { - $installScript = "$dotnetRoot\dotnet-install.ps1" + $installScript = Join-Path $dotnetRoot "dotnet-install.ps1" if (!(Test-Path $installScript)) { Create-Directory $dotnetRoot Invoke-WebRequest "https://dot.net/v1/dotnet-install.ps1" -OutFile $installScript @@ -162,11 +228,23 @@ function GetDotNetInstallScript([string] $dotnetRoot) { } function InstallDotNetSdk([string] $dotnetRoot, [string] $version, [string] $architecture = "") { + InstallDotNet $dotnetRoot $version $architecture +} + +function InstallDotNet([string] $dotnetRoot, [string] $version, [string] $architecture = "", [string] $runtime = "", [bool] $skipNonVersionedFiles = $false) { $installScript = GetDotNetInstallScript $dotnetRoot $installScript = GetDotNetInstallScript $dotnetRoot - $archArg = if ($architecture) { $architecture } else { "" } - & $installScript -Version $version -InstallDir $dotnetRoot -Architecture $archArg + $installParameters = @{ + Version = $version + InstallDir = $dotnetRoot + } + + if ($architecture) { $installParameters.Architecture = $architecture } + if ($runtime) { $installParameters.Runtime = $runtime } + if ($skipNonVersionedFiles) { $installParameters.SkipNonVersionedFiles = $skipNonVersionedFiles } + + & $installScript @installParameters if ($lastExitCode -ne 0) { - Write-Host "Failed to install dotnet cli (exit code '$lastExitCode')." -ForegroundColor Red + Write-PipelineTaskError -Message "Failed to install dotnet cli (exit code '$lastExitCode')." ExitWithExitCode $lastExitCode } } @@ -195,7 +273,11 @@ function InitializeVisualStudioMSBuild([bool]$install, [object]$vsRequirements = if ($env:VSINSTALLDIR -ne $null) { $msbuildCmd = Get-Command "msbuild.exe" -ErrorAction SilentlyContinue if ($msbuildCmd -ne $null) { - if ($msbuildCmd.Version -ge $vsMinVersion) { + # Workaround for https://github.com/dotnet/roslyn/issues/35793 + # Due to this issue $msbuildCmd.Version returns 0.0.0.0 for msbuild.exe 16.2+ + $msbuildVersion = [Version]::new((Get-Item $msbuildCmd.Path).VersionInfo.ProductVersion.Split(@('-', '+'))[0]) + + if ($msbuildVersion -ge $vsMinVersion) { return $global:_MSBuildExe = $msbuildCmd.Path } @@ -336,22 +418,22 @@ function InitializeBuildTool() { if ($msbuildEngine -eq "dotnet") { if (!$dotnetRoot) { - Write-Host "/global.json must specify 'tools.dotnet'." -ForegroundColor Red + Write-PipelineTaskError "/global.json must specify 'tools.dotnet'." ExitWithExitCode 1 } - $buildTool = @{ Path = Join-Path $dotnetRoot "dotnet.exe"; Command = "msbuild" } + $buildTool = @{ Path = Join-Path $dotnetRoot "dotnet.exe"; Command = "msbuild"; Tool = "dotnet"; Framework = "netcoreapp2.1" } } elseif ($msbuildEngine -eq "vs") { try { $msbuildPath = InitializeVisualStudioMSBuild -install:$restore } catch { - Write-Host $_ -ForegroundColor Red + Write-PipelineTaskError $_ ExitWithExitCode 1 } - $buildTool = @{ Path = $msbuildPath; Command = "" } + $buildTool = @{ Path = $msbuildPath; Command = ""; Tool = "vs"; Framework = "net472" } } else { - Write-Host "Unexpected value of -msbuildEngine: '$msbuildEngine'." -ForegroundColor Red + Write-PipelineTaskError "Unexpected value of -msbuildEngine: '$msbuildEngine'." ExitWithExitCode 1 } @@ -368,7 +450,7 @@ function GetDefaultMSBuildEngine() { return "dotnet" } - Write-Host "-msbuildEngine must be specified, or /global.json must specify 'tools.dotnet' or 'tools.vs'." -ForegroundColor Red + Write-PipelineTaskError "-msbuildEngine must be specified, or /global.json must specify 'tools.dotnet' or 'tools.vs'." ExitWithExitCode 1 } @@ -391,6 +473,16 @@ function GetSdkTaskProject([string]$taskName) { return Join-Path (Split-Path (InitializeToolset) -Parent) "SdkTasks\$taskName.proj" } +function InitializeNativeTools() { + if (Get-Member -InputObject $GlobalJson -Name "native-tools") { + $nativeArgs="" + if ($ci) { + $nativeArgs = "-InstallDirectory $ToolsDir" + } + Invoke-Expression "& `"$PSScriptRoot/init-tools-native.ps1`" $nativeArgs" + } +} + function InitializeToolset() { if (Test-Path variable:global:_ToolsetBuildProj) { return $global:_ToolsetBuildProj @@ -409,7 +501,7 @@ function InitializeToolset() { } if (-not $restore) { - Write-Host "Toolset version $toolsetVersion has not been restored." -ForegroundColor Red + Write-PipelineTaskError "Toolset version $toolsetVersion has not been restored." ExitWithExitCode 1 } @@ -419,7 +511,8 @@ function InitializeToolset() { $bl = if ($binaryLog) { "/bl:" + (Join-Path $LogDir "ToolsetRestore.binlog") } else { "" } '' | Set-Content $proj - MSBuild $proj $bl /t:__WriteToolsetLocation /clp:ErrorsOnly`;NoSummary /p:__ToolsetLocationOutputFile=$toolsetLocationFile + + MSBuild-Core $proj $bl /t:__WriteToolsetLocation /clp:ErrorsOnly`;NoSummary /p:__ToolsetLocationOutputFile=$toolsetLocationFile $path = Get-Content $toolsetLocationFile -TotalCount 1 if (!(Test-Path $path)) { @@ -449,6 +542,23 @@ function Stop-Processes() { # Terminates the script if the build fails. # function MSBuild() { + if ($pipelinesLog) { + $buildTool = InitializeBuildTool + $toolsetBuildProject = InitializeToolset + $path = Split-Path -parent $toolsetBuildProject + $path = Join-Path $path (Join-Path $buildTool.Framework "Microsoft.DotNet.Arcade.Sdk.dll") + $args += "/logger:$path" + } + + MSBuild-Core @args +} + +# +# Executes msbuild (or 'dotnet msbuild') with arguments passed to the function. +# The arguments are automatically quoted. +# Terminates the script if the build fails. +# +function MSBuild-Core() { if ($ci) { if (!$binaryLog) { throw "Binary log must be enabled in CI build." @@ -476,7 +586,7 @@ function MSBuild() { $exitCode = Exec-Process $buildTool.Path $cmdArgs if ($exitCode -ne 0) { - Write-Host "Build failed." -ForegroundColor Red + Write-PipelineTaskError "Build failed." $buildLog = GetMSBuildBinaryLogCommandLineArgument $args if ($buildLog -ne $null) { @@ -504,6 +614,8 @@ function GetMSBuildBinaryLogCommandLineArgument($arguments) { return $null } +. $PSScriptRoot\LoggingCommandFunctions.ps1 + $RepoRoot = Resolve-Path (Join-Path $PSScriptRoot "..\..") $EngRoot = Resolve-Path (Join-Path $PSScriptRoot "..") $ArtifactsDir = Join-Path $RepoRoot "artifacts" @@ -512,16 +624,15 @@ $ToolsDir = Join-Path $RepoRoot ".tools" $LogDir = Join-Path (Join-Path $ArtifactsDir "log") $configuration $TempDir = Join-Path (Join-Path $ArtifactsDir "tmp") $configuration $GlobalJson = Get-Content -Raw -Path (Join-Path $RepoRoot "global.json") | ConvertFrom-Json +# true if global.json contains a "runtimes" section +$globalJsonHasRuntimes = if ($GlobalJson.tools.PSObject.Properties.Name -Match 'runtimes') { $true } else { $false } Create-Directory $ToolsetDir Create-Directory $TempDir Create-Directory $LogDir -if ($ci) { - Write-Host "##vso[task.setvariable variable=Artifacts]$ArtifactsDir" - Write-Host "##vso[task.setvariable variable=Artifacts.Toolset]$ToolsetDir" - Write-Host "##vso[task.setvariable variable=Artifacts.Log]$LogDir" - - $env:TEMP = $TempDir - $env:TMP = $TempDir -} +Write-PipelineSetVariable -Name 'Artifacts' -Value $ArtifactsDir +Write-PipelineSetVariable -Name 'Artifacts.Toolset' -Value $ToolsetDir +Write-PipelineSetVariable -Name 'Artifacts.Log' -Value $LogDir +Write-PipelineSetVariable -Name 'TEMP' -Value $TempDir +Write-PipelineSetVariable -Name 'TMP' -Value $TempDir diff --git a/eng/common/tools.sh b/eng/common/tools.sh index ecdece1f8..fd26f6fbb 100644 --- a/eng/common/tools.sh +++ b/eng/common/tools.sh @@ -1,8 +1,20 @@ +#!/usr/bin/env bash + # Initialize variables if they aren't already defined. # CI mode - set to true on CI server for PR validation build or official build. ci=${ci:-false} +# Set to true to use the pipelines logger which will enable Azure logging output. +# https://github.com/Microsoft/azure-pipelines-tasks/blob/master/docs/authoring/commands.md +# This flag is meant as a temporary opt-opt for the feature while validate it across +# our consumers. It will be deleted in the future. +if [[ "$ci" == true ]]; then + pipelines_log=${pipelines_log:-true} +else + pipelines_log=${pipelines_log:-false} +fi + # Build configuration. Common values include 'Debug' and 'Release', but the repository may use other names. configuration=${configuration:-'Debug'} @@ -40,6 +52,78 @@ else use_global_nuget_cache=${use_global_nuget_cache:-true} fi +function EmitError { + if [[ "$ci" != true ]]; then + echo "$@" >&2 + return + fi + + message_type="error" + sourcepath='' + linenumber='' + columnnumber='' + error_code='' + + while [[ $# -gt 0 ]]; do + opt="$(echo "${1/#--/-}" | awk '{print tolower($0)}')" + case "$opt" in + -type|-t) + message_type=$2 + shift + ;; + -sourcepath|-s) + sourcepath=$2 + shift + ;; + -linenumber|-l) + linenumber=$2 + shift + ;; + -columnnumber|-col) + columnnumber=$2 + shift + ;; + -code|-c) + error_code=$2 + shift + ;; + *) + break + ;; + esac + + shift + done + + message='##vso[task.logissue' + + message="$message type=$message_type" + + if [ -n "$sourcepath" ]; then + message="$message;sourcepath=$sourcepath" + else + message="$message;sourcepath=${BASH_SOURCE[1]}" + fi + + if [ -n "$linenumber" ]; then + message="$message;linenumber=$linenumber" + else + message="$message;linenumber=${BASH_LINENO[0]}" + fi + + if [ -n "$columnnumber" ]; then + message="$message;columnnumber=$columnnumber" + fi + + if [ -n "$error_code" ]; then + message="$message;code=$error_code" + fi + + message="$message]$*" + + echo "$message" +} + # Resolve any symlinks in the given path. function ResolvePath { local path=$1 @@ -65,7 +149,7 @@ function ReadGlobalVersion { local pattern="\"$key\" *: *\"(.*)\"" if [[ ! $line =~ $pattern ]]; then - echo "Error: Cannot find \"$key\" in $global_json_file" >&2 + EmitError "Error: Cannot find \"$key\" in $global_json_file" ExitWithExitCode 1 fi @@ -101,7 +185,7 @@ function InitializeDotNetCli { fi # Find the first path on $PATH that contains the dotnet.exe - if [[ "$use_installed_dotnet_cli" == true && -z "${DOTNET_INSTALL_DIR:-}" ]]; then + if [[ "$use_installed_dotnet_cli" == true && $global_json_has_runtimes == false && -z "${DOTNET_INSTALL_DIR:-}" ]]; then local dotnet_path=`command -v dotnet` if [[ -n "$dotnet_path" ]]; then ResolvePath "$dotnet_path" @@ -115,17 +199,18 @@ function InitializeDotNetCli { # Use dotnet installation specified in DOTNET_INSTALL_DIR if it contains the required SDK version, # otherwise install the dotnet CLI and SDK to repo local .dotnet directory to avoid potential permission issues. - if [[ -n "${DOTNET_INSTALL_DIR:-}" && -d "$DOTNET_INSTALL_DIR/sdk/$dotnet_sdk_version" ]]; then + if [[ $global_json_has_runtimes == false && -n "${DOTNET_INSTALL_DIR:-}" && -d "$DOTNET_INSTALL_DIR/sdk/$dotnet_sdk_version" ]]; then dotnet_root="$DOTNET_INSTALL_DIR" else dotnet_root="$repo_root/.dotnet" + export DOTNET_INSTALL_DIR="$dotnet_root" if [[ ! -d "$DOTNET_INSTALL_DIR/sdk/$dotnet_sdk_version" ]]; then if [[ "$install" == true ]]; then InstallDotNetSdk "$dotnet_root" "$dotnet_sdk_version" else - echo "Unable to find dotnet with SDK version '$dotnet_sdk_version'" >&2 + EmitError "Unable to find dotnet with SDK version '$dotnet_sdk_version'" ExitWithExitCode 1 fi fi @@ -149,18 +234,36 @@ function InitializeDotNetCli { function InstallDotNetSdk { local root=$1 local version=$2 + local architecture="" + if [[ $# == 3 ]]; then + architecture=$3 + fi + InstallDotNet "$root" "$version" $architecture +} +function InstallDotNet { + local root=$1 + local version=$2 + GetDotNetInstallScript "$root" local install_script=$_GetDotNetInstallScript - local arch_arg="" - if [[ $# == 3 ]]; then - arch_arg="--architecture $3" + local archArg='' + if [[ -n "${3:-}" ]]; then + archArg="--architecture $3" + fi + local runtimeArg='' + if [[ -n "${4:-}" ]]; then + runtimeArg="--runtime $4" fi - bash "$install_script" --version $version --install-dir "$root" $arch_arg || { + local skipNonVersionedFilesArg="" + if [[ "$#" -ge "5" ]]; then + skipNonVersionedFilesArg="--skip-non-versioned-files" + fi + bash "$install_script" --version $version --install-dir "$root" $archArg $runtimeArg $skipNonVersionedFilesArg || { local exit_code=$? - echo "Failed to install dotnet SDK (exit code '$exit_code')." >&2 + EmitError "Failed to install dotnet SDK (exit code '$exit_code')." ExitWithExitCode $exit_code } } @@ -197,6 +300,7 @@ function InitializeBuildTool { # return values _InitializeBuildTool="$_InitializeDotNetCli/dotnet" _InitializeBuildToolCommand="msbuild" + _InitializeBuildToolFramework="netcoreapp2.1" } function GetNuGetPackageCachePath { @@ -212,6 +316,17 @@ function GetNuGetPackageCachePath { _GetNuGetPackageCachePath=$NUGET_PACKAGES } +function InitializeNativeTools() { + if grep -Fq "native-tools" $global_json_file + then + local nativeArgs="" + if [[ "$ci" == true ]]; then + nativeArgs="-InstallDirectory $tools_dir" + fi + "$_script_dir/init-tools-native.sh" $nativeArgs + fi +} + function InitializeToolset { if [[ -n "${_InitializeToolset:-}" ]]; then return @@ -234,7 +349,7 @@ function InitializeToolset { fi if [[ "$restore" != true ]]; then - echo "Toolset version $toolsetVersion has not been restored." >&2 + EmitError "Toolset version $toolsetVersion has not been restored." ExitWithExitCode 2 fi @@ -246,12 +361,12 @@ function InitializeToolset { fi echo '' > "$proj" - MSBuild "$proj" $bl /t:__WriteToolsetLocation /clp:ErrorsOnly\;NoSummary /p:__ToolsetLocationOutputFile="$toolset_location_file" + MSBuild-Core "$proj" $bl /t:__WriteToolsetLocation /clp:ErrorsOnly\;NoSummary /p:__ToolsetLocationOutputFile="$toolset_location_file" local toolset_build_proj=`cat "$toolset_location_file"` if [[ ! -a "$toolset_build_proj" ]]; then - echo "Invalid toolset path: $toolset_build_proj" >&2 + EmitError "Invalid toolset path: $toolset_build_proj" ExitWithExitCode 3 fi @@ -274,14 +389,27 @@ function StopProcesses { } function MSBuild { + local args=$@ + if [[ "$pipelines_log" == true ]]; then + InitializeBuildTool + InitializeToolset + local toolset_dir="${_InitializeToolset%/*}" + local logger_path="$toolset_dir/$_InitializeBuildToolFramework/Microsoft.DotNet.Arcade.Sdk.dll" + args=( "${args[@]}" "-logger:$logger_path" ) + fi + + MSBuild-Core ${args[@]} +} + +function MSBuild-Core { if [[ "$ci" == true ]]; then if [[ "$binary_log" != true ]]; then - echo "Binary log must be enabled in CI build." >&2 + EmitError "Binary log must be enabled in CI build." ExitWithExitCode 1 fi if [[ "$node_reuse" == true ]]; then - echo "Node reuse must be disabled in CI build." >&2 + EmitError "Node reuse must be disabled in CI build." ExitWithExitCode 1 fi fi @@ -295,7 +423,7 @@ function MSBuild { "$_InitializeBuildTool" "$_InitializeBuildToolCommand" /m /nologo /clp:Summary /v:$verbosity /nr:$node_reuse $warnaserror_switch /p:TreatWarningsAsErrors=$warn_as_error /p:ContinuousIntegrationBuild=$ci "$@" || { local exit_code=$? - echo "Build failed (exit code '$exit_code')." >&2 + EmitError "Build failed (exit code '$exit_code')." ExitWithExitCode $exit_code } } @@ -307,10 +435,17 @@ eng_root=`cd -P "$_script_dir/.." && pwd` repo_root=`cd -P "$_script_dir/../.." && pwd` artifacts_dir="$repo_root/artifacts" toolset_dir="$artifacts_dir/toolset" +tools_dir="$repo_root/.tools" log_dir="$artifacts_dir/log/$configuration" temp_dir="$artifacts_dir/tmp/$configuration" global_json_file="$repo_root/global.json" +# determine if global.json contains a "runtimes" entry +global_json_has_runtimes=false +dotnetlocal_key=`grep -m 1 "runtimes" "$global_json_file"` || true +if [[ -n "$dotnetlocal_key" ]]; then + global_json_has_runtimes=true +fi # HOME may not be defined in some scenarios, but it is required by NuGet if [[ -z $HOME ]]; then @@ -325,4 +460,4 @@ mkdir -p "$log_dir" if [[ $ci == true ]]; then export TEMP="$temp_dir" export TMP="$temp_dir" -fi +fi \ No newline at end of file diff --git a/eng/restore-toolset.ps1 b/eng/restore-toolset.ps1 index a1c99361b..69e507180 100644 --- a/eng/restore-toolset.ps1 +++ b/eng/restore-toolset.ps1 @@ -16,7 +16,10 @@ function InitializeCustomSDKToolset { $env:DOTNET_CLI_TELEMETRY_PROFILE='$env:DOTNET_CLI_TELEMETRY_PROFILE;https://github.com/dotnet/roslyn-sdk' $cli = InitializeDotnetCli -install:$true - InstallDotNetSharedFramework "1.1.10" + InstallDotNetSharedFramework "1.1.12" + InstallDotNetSharedFramework "2.0.9" + InstallDotNetSharedFramework "2.1.10" + InstallDotNetSharedFramework "2.2.5" } function InstallDotNetSharedFramework([string]$version) { diff --git a/global.json b/global.json index cd90071ad..cb6836f1b 100644 --- a/global.json +++ b/global.json @@ -1,12 +1,12 @@ { "tools": { - "dotnet": "2.2.103", + "dotnet": "3.0.100-preview5-011568", "vs": { "version": "15.9" }, "xcopy-msbuild": "15.9.0-alpha" }, "msbuild-sdks": { - "Microsoft.DotNet.Arcade.Sdk": "1.0.0-beta.19230.6" + "Microsoft.DotNet.Arcade.Sdk": "1.0.0-beta.19304.1" } }