diff --git a/FSharpBuild.Directory.Build.props b/FSharpBuild.Directory.Build.props
index a1ba7ab156..6687fb4088 100644
--- a/FSharpBuild.Directory.Build.props
+++ b/FSharpBuild.Directory.Build.props
@@ -11,8 +11,7 @@
$(RepoRoot)src
$(ArtifactsDir)\SymStore
- $(ArtifactsDir)\Bootstrap
- $(ArtifactsDir)/fsc/Proto/netcoreapp2.1
+ $(ArtifactsDir)\Bootstrap
4.4.0
1182;0025;$(WarningsAsErrors)
@@ -76,6 +75,7 @@
https://github.com/Microsoft/visualfsharp
git
+
<_DotGitDir>$(RepoRoot).git
<_HeadFileContent Condition="Exists('$(_DotGitDir)/HEAD')">$([System.IO.File]::ReadAllText('$(_DotGitDir)/HEAD').Trim())
@@ -88,7 +88,7 @@
$(NoWarn);FS2003
true
- portable
+ embedded
fs
false
true
@@ -96,10 +96,10 @@
- $(ProtoOutputPath)\Microsoft.FSharp.Targets
- $(ProtoOutputPath)\Microsoft.FSharp.NetSdk.props
- $(ProtoOutputPath)\Microsoft.FSharp.NetSdk.targets
- $(ProtoOutputPath)\Microsoft.FSharp.Overrides.NetSdk.targets
+ $(ProtoOutputPath)\fsc\Microsoft.FSharp.Targets
+ $(ProtoOutputPath)\fsc\Microsoft.FSharp.NetSdk.props
+ $(ProtoOutputPath)\fsc\Microsoft.FSharp.NetSdk.targets
+ $(ProtoOutputPath)\fsc\Microsoft.FSharp.Overrides.NetSdk.targets
diff --git a/FSharpTests.Directory.Build.props b/FSharpTests.Directory.Build.props
new file mode 100644
index 0000000000..8a7a832a43
--- /dev/null
+++ b/FSharpTests.Directory.Build.props
@@ -0,0 +1,47 @@
+
+
+
+ true
+
+
+
+ true
+
+ $(MSBuildThisFileDirectory)artifacts\bin\fsc\$(Configuration)\net472
+ fsc.exe
+
+
+ $(MSBuildThisFileDirectory)artifacts\bin\fsi\$(Configuration)\net472
+ fsi.exe
+
+
+
+
+ true
+
+ $([System.IO.Path]::GetDirectoryName('$(DOTNET_HOST_PATH)'))
+ dotnet.exe
+ dotnet
+ $(MSBuildThisFileDirectory)artifacts\bin\fsc\$(Configuration)\netcoreapp2.1\fsc.exe
+
+ $([System.IO.Path]::GetDirectoryName('$(DOTNET_HOST_PATH)'))
+ dotnet.exe
+ dotnet
+ $(MSBuildThisFileDirectory)artifacts\bin\fsi\$(Configuration)\netcoreapp2.1\fsi.exe
+
+
+
+
+ <_FSharpBuildTargetFramework Condition="'$(MSBuildRuntimeType)'!='Core'">net472
+ <_FSharpBuildTargetFramework Condition="'$(MSBuildRuntimeType)'=='Core'">netcoreapp2.1
+ <_FSharpBuildBinPath>$(MSBuildThisFileDirectory)artifacts\bin\fsc\$(Configuration)\$(_FSharpBuildTargetFramework)
+
+ $(_FSharpBuildBinPath)\FSharp.Build.dll
+
+ $(_FSharpBuildBinPath)/Microsoft.FSharp.Targets
+ $(_FSharpBuildBinPath)/Microsoft.FSharp.NetSdk.props
+ $(_FSharpBuildBinPath)/Microsoft.FSharp.NetSdk.targets
+ $(_FSharpBuildBinPath)/Microsoft.FSharp.Overrides.NetSdk.targets
+
+
+
diff --git a/NuGet.config b/NuGet.config
index fdf6d3eda4..df85afb048 100644
--- a/NuGet.config
+++ b/NuGet.config
@@ -1,4 +1,4 @@
-
+
@@ -8,6 +8,26 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/RoslynPackageVersion.txt b/RoslynPackageVersion.txt
index fd1d6f6d9b..2b54870d02 100644
--- a/RoslynPackageVersion.txt
+++ b/RoslynPackageVersion.txt
@@ -1 +1 @@
-3.1.0-beta3-19222-02
+3.2.0-beta4-19312-15
\ No newline at end of file
diff --git a/azure-pipelines.yml b/azure-pipelines.yml
deleted file mode 100644
index 2207a4792e..0000000000
--- a/azure-pipelines.yml
+++ /dev/null
@@ -1,306 +0,0 @@
-# CI and PR triggers
-trigger:
-- master
-- dev16.1
-- feature/*
-- release/*
-pr:
-- master
-- dev16.1
-- feature/*
-- release/*
-
-variables:
- - name: _TeamName
- value: FSharp
- - name: _BuildConfig
- value: Release
- - name: _PublishUsingPipelines
- value: true
- - name: _DotNetArtifactsCategory
- value: .NETCore
- - name: VisualStudioDropName
- value: Products/$(System.TeamProject)/$(Build.Repository.Name)/$(Build.SourceBranchName)/$(Build.BuildNumber)
-
-# Variables defined in yml cannot be overridden at queue time; instead overridable variables must be defined in the web UI.
-# Commenting out until something like this is supported: https://github.com/Microsoft/azure-pipelines-yaml/pull/129
-#variables:
-#- name: SkipTests
-# defaultValue: false
-
-jobs:
-
-#---------------------------------------------------------------------------------------------------------------------#
-# Signed build #
-#---------------------------------------------------------------------------------------------------------------------#
-- ${{ if and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}:
- - template: /eng/common/templates/jobs/jobs.yml
- parameters:
- enableMicrobuild: true
- enablePublishBuildArtifacts: true
- enablePublishTestResults: false
- enablePublishBuildAssets: true
- enablePublishUsingPipelines: $(_PublishUsingPipelines)
- enableTelemetry: true
- helixRepo: dotnet/fsharp
- jobs:
- - job: Full_Signed
- pool:
- name: NetCoreInternal-Int-Pool
- queue: buildpool.windows.10.amd64.vs2019
- timeoutInMinutes: 300
- variables:
- - group: DotNet-Blob-Feed
- - group: DotNet-Symbol-Server-Pats
- - name: _SignType
- value: Real
- - name: _DotNetPublishToBlobFeed
- value: true
- steps:
- - checkout: self
- clean: true
- - script: eng\CIBuild.cmd
- -configuration $(_BuildConfig)
- -prepareMachine
- -testAll
- -officialSkipTests $(SkipTests)
- /p:SignType=$(_SignType)
- /p:DotNetSignType=$(_SignType)
- /p:MicroBuild_SigningEnabled=true
- /p:OverridePackageSource=https://dotnetfeed.blob.core.windows.net/dotnet-core/index.json
- /p:TeamName=$(_TeamName)
- /p:DotNetPublishBlobFeedKey=$(dotnetfeed-storage-access-key-1)
- /p:DotNetPublishBlobFeedUrl=https://dotnetfeed.blob.core.windows.net/dotnet-core/index.json
- /p:DotNetPublishToBlobFeed=true
- /p:DotNetPublishUsingPipelines=$(_PublishUsingPipelines)
- /p:DotNetArtifactsCategory=$(_DotNetArtifactsCategory)
- /p:DotNetSymbolServerTokenMsdl=$(microsoft-symbol-server-pat)
- /p:DotNetSymbolServerTokenSymWeb=$(symweb-symbol-server-pat)
- /p:OfficialBuildId=$(BUILD.BUILDNUMBER)
- /p:PublishToSymbolServer=true
- /p:VisualStudioDropName=$(VisualStudioDropName)
- - task: PublishTestResults@2
- displayName: Publish Test Results
- inputs:
- testResultsFormat: 'NUnit'
- testResultsFiles: '*.xml'
- searchFolder: '$(Build.SourcesDirectory)/artifacts/TestResults/$(_BuildConfig)'
- continueOnError: true
- condition: ne(variables['SkipTests'], 'true')
- - task: PublishBuildArtifacts@1
- displayName: Publish Test Logs
- inputs:
- PathtoPublish: '$(Build.SourcesDirectory)\artifacts\TestResults\$(_BuildConfig)'
- ArtifactName: 'Test Logs'
- publishLocation: Container
- continueOnError: true
- condition: ne(variables['SkipTests'], 'true')
- - task: PublishBuildArtifacts@1
- displayName: Publish Artifact Packages
- inputs:
- PathtoPublish: '$(Build.SourcesDirectory)\artifacts\packages\$(_BuildConfig)'
- ArtifactName: 'Packages'
- condition: succeeded()
- - task: PublishBuildArtifacts@1
- displayName: Publish Artifact VSSetup
- inputs:
- PathtoPublish: '$(Build.SourcesDirectory)\artifacts\VSSetup\$(_BuildConfig)\Insertion'
- ArtifactName: 'VSSetup'
- condition: succeeded()
- - task: PublishBuildArtifacts@1
- displayName: Publish Artifact Nightly
- inputs:
- PathtoPublish: '$(Build.SourcesDirectory)\artifacts\VSSetup\$(_BuildConfig)\VisualFSharpFull.vsix'
- ArtifactName: 'Nightly'
- condition: succeeded()
-
-#---------------------------------------------------------------------------------------------------------------------#
-# PR builds #
-#---------------------------------------------------------------------------------------------------------------------#
-- ${{ if eq(variables['System.TeamProject'], 'public') }}:
- - template: /eng/common/templates/jobs/jobs.yml
- parameters:
- enableMicrobuild: true
- enablePublishBuildArtifacts: true
- enablePublishTestResults: false
- enablePublishBuildAssets: true
- enablePublishUsingPipelines: $(_PublishUsingPipelines)
- enableTelemetry: true
- helixRepo: dotnet/fsharp
- jobs:
-
- # Windows
- - job: Windows
- pool:
- vmImage: windows-2019
- timeoutInMinutes: 120
- strategy:
- maxParallel: 4
- matrix:
- desktop_release:
- _configuration: Release
- _testKind: testDesktop
- coreclr_release:
- _configuration: Release
- _testKind: testCoreclr
- fsharpqa_release:
- _configuration: Release
- _testKind: testFSharpQA
- vs_release:
- _configuration: Release
- _testKind: testVs
- steps:
- - checkout: self
- clean: true
- - script: eng\CIBuild.cmd -configuration $(_configuration) -$(_testKind)
- displayName: Build / Test
- - task: PublishTestResults@2
- displayName: Publish Test Results
- inputs:
- testResultsFormat: 'NUnit'
- testResultsFiles: '*.xml'
- searchFolder: '$(Build.SourcesDirectory)/artifacts/TestResults/$(_configuration)'
- continueOnError: true
- condition: ne(variables['_testKind'], 'testFSharpQA')
- - task: PublishBuildArtifacts@1
- displayName: Publish Test Logs
- inputs:
- PathtoPublish: '$(Build.SourcesDirectory)\artifacts\TestResults\$(_configuration)'
- ArtifactName: 'Windows $(_configuration) $(_testKind) test logs'
- publishLocation: Container
- continueOnError: true
- condition: eq(variables['_testKind'], 'testFSharpQA')
-
- # Linux
- - job: Linux
- pool:
- vmImage: ubuntu-16.04
- variables:
- - name: _SignType
- value: Test
- steps:
- - checkout: self
- clean: true
- - script: ./eng/cibuild.sh --configuration $(_BuildConfig) --testcoreclr
- displayName: Build / Test
- - task: PublishTestResults@2
- displayName: Publish Test Results
- inputs:
- testResultsFormat: 'NUnit'
- testResultsFiles: '*.xml'
- searchFolder: '$(Build.SourcesDirectory)/artifacts/TestResults/$(_BuildConfig)'
- continueOnError: true
- condition: always()
-
- # MacOS
- - job: MacOS
- pool:
- vmImage: macOS-10.13
- variables:
- - name: _SignType
- value: Test
- steps:
- - checkout: self
- clean: true
- - script: ./eng/cibuild.sh --configuration $(_BuildConfig) --testcoreclr
- displayName: Build / Test
- - task: PublishTestResults@2
- displayName: Publish Test Results
- inputs:
- testResultsFormat: 'NUnit'
- testResultsFiles: '*.xml'
- searchFolder: '$(Build.SourcesDirectory)/artifacts/TestResults/$(_BuildConfig)'
- continueOnError: true
- condition: always()
-
- # Source Build Linux
- - job: SourceBuild_Linux
- pool:
- vmImage: ubuntu-16.04
- steps:
- - checkout: self
- clean: true
- - script: ./eng/cibuild.sh --configuration Release /p:DotNetBuildFromSource=true /p:FSharpSourceBuild=true
- displayName: Build
-
- # Source Build Windows
- - job: SourceBuild_Windows
- pool:
- vmImage: windows-2019
- steps:
- - checkout: self
- clean: true
- - script: eng\CIBuild.cmd -configuration Release -noSign /p:DotNetBuildFromSource=true /p:FSharpSourceBuild=true
- displayName: Build
-
- # Up-to-date
- - job: UpToDate_Windows
- pool:
- vmImage: windows-2019
- steps:
- - checkout: self
- clean: true
- - task: PowerShell@2
- displayName: Run up-to-date build check
- inputs:
- filePath: eng\tests\UpToDate.ps1
- arguments: -configuration $(_BuildConfig) -ci -binaryLog
-
-#---------------------------------------------------------------------------------------------------------------------#
-# FCS builds #
-#---------------------------------------------------------------------------------------------------------------------#
-
-- ${{ if eq(variables['System.TeamProject'], 'public') }}:
- - template: /eng/common/templates/jobs/jobs.yml
- parameters:
- enableMicrobuild: true
- enablePublishTestResults: false
- enablePublishBuildAssets: true
- enablePublishUsingPipelines: false
- enableTelemetry: true
- helixRepo: dotnet/fsharp
- jobs:
-
- - job: Windows_FCS
- pool:
- vmImage: windows-2019
- variables:
- - name: _SignType
- value: Test
- steps:
- - checkout: self
- clean: true
- - script: fcs\build.cmd TestAndNuget
- displayName: Build / Test
- - task: PublishTestResults@2
- displayName: Publish Test Results
- inputs:
- testResultsFormat: 'NUnit'
- testResultsFiles: '*.xml'
- searchFolder: '$(Build.SourcesDirectory)/artifacts/TestResults/Release'
- continueOnError: true
- condition: always()
-
- - job: Linux_FCS
- pool:
- vmImage: ubuntu-16.04
- variables:
- - name: _SignType
- value: Test
- steps:
- - checkout: self
- clean: true
- - script: ./fcs/build.sh Build
- displayName: Build
-
- - job: MacOS_FCS
- pool:
- vmImage: macOS-10.13
- variables:
- - name: _SignType
- value: Test
- steps:
- - checkout: self
- clean: true
- - script: ./fcs/build.sh Build
- displayName: Build
diff --git a/eng/Build.ps1 b/eng/Build.ps1
index ac5675ae7e..75f0178b7d 100644
--- a/eng/Build.ps1
+++ b/eng/Build.ps1
@@ -69,6 +69,7 @@ function Print-Usage() {
Write-Host ""
Write-Host "Actions:"
Write-Host " -restore Restore packages (short: -r)"
+ Write-Host " -norestore Don't restore packages"
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"
@@ -108,6 +109,7 @@ function Process-Arguments() {
Print-Usage
exit 0
}
+ $script:nodeReuse = $False;
if ($testAll) {
$script:testDesktop = $True
@@ -172,7 +174,7 @@ function BuildSolution() {
$officialBuildId = if ($official) { $env:BUILD_BUILDNUMBER } else { "" }
$toolsetBuildProj = InitializeToolset
$quietRestore = !$ci
- $testTargetFrameworks = if ($testCoreClr) { "netcoreapp2.1" } else { "" }
+ $testTargetFrameworks = if ($testCoreClr) { "netcoreapp3.0" } else { "" }
# Do not set the property to true explicitly, since that would override value projects might set.
$suppressExtensionDeployment = if (!$deployExtensions) { "/p:DeployExtension=false" } else { "" }
@@ -190,7 +192,6 @@ function BuildSolution() {
/p:Publish=$publish `
/p:ContinuousIntegrationBuild=$ci `
/p:OfficialBuildId=$officialBuildId `
- /p:BootstrapBuildPath=$bootstrapDir `
/p:QuietRestore=$quietRestore `
/p:QuietRestoreBinaryLog=$binaryLog `
/p:TestTargetFrameworks=$testTargetFrameworks `
@@ -223,13 +224,14 @@ function UpdatePath() {
TestAndAddToPath "$ArtifactsDir\bin\fsiAnyCpu\$configuration\net472"
}
-function VerifyAssemblyVersions() {
- $fsiPath = Join-Path $ArtifactsDir "bin\fsi\Proto\net472\fsi.exe"
+function VerifyAssemblyVersionsAndSymbols() {
+ $assemblyVerCheckPath = Join-Path $ArtifactsDir "Bootstrap\AssemblyCheck\AssemblyCheck.dll"
# Only verify versions on CI or official build
if ($ci -or $official) {
- $asmVerCheckPath = "$RepoRoot\scripts"
- Exec-Console $fsiPath """$asmVerCheckPath\AssemblyVersionCheck.fsx"" -- ""$ArtifactsDir"""
+ $dotnetPath = InitializeDotNetCli
+ $dotnetExe = Join-Path $dotnetPath "dotnet.exe"
+ Exec-Console $dotnetExe """$assemblyVerCheckPath"" ""$ArtifactsDir"""
}
}
@@ -275,6 +277,25 @@ function Prepare-TempDir() {
Copy-Item (Join-Path $RepoRoot "tests\Resources\Directory.Build.targets") $TempDir
}
+function EnablePreviewSdks() {
+ if (Test-Path variable:global:_MSBuildExe) {
+ return
+ }
+ $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
+}
+
try {
Process-Arguments
@@ -286,8 +307,9 @@ try {
if ($ci) {
Prepare-TempDir
+ EnablePreviewSdks
- # enable us to build netcoreapp2.1 binaries
+ # enable us to build netcoreapp2.1 product binaries
$global:_DotNetInstallDir = Join-Path $RepoRoot ".dotnet"
InstallDotNetSdk $global:_DotNetInstallDir $GlobalJson.tools.dotnet
InstallDotNetSdk $global:_DotNetInstallDir "2.1.503"
@@ -306,11 +328,11 @@ try {
}
if ($build) {
- VerifyAssemblyVersions
+ VerifyAssemblyVersionsAndSymbols
}
$desktopTargetFramework = "net472"
- $coreclrTargetFramework = "netcoreapp2.1"
+ $coreclrTargetFramework = "netcoreapp3.0"
if ($testDesktop -and -not $noVisualStudio) {
TestUsingNUnit -testProject "$RepoRoot\tests\FSharp.Compiler.UnitTests\FSharp.Compiler.UnitTests.fsproj" -targetFramework $desktopTargetFramework
diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml
index 309516901a..848ec45335 100644
--- a/eng/Version.Details.xml
+++ b/eng/Version.Details.xml
@@ -3,9 +3,9 @@
-
+
https://github.com/dotnet/arcade
- 9946534da4f73e6242ca105f6798ab58119c9ab0
+ e2f5f0f5c20a1fef71845795b09066a5cd892a7e
diff --git a/eng/Versions.props b/eng/Versions.props
index 5b4d32757a..4a8ca4fbc4 100644
--- a/eng/Versions.props
+++ b/eng/Versions.props
@@ -23,14 +23,14 @@
$(FSCorePackageVersion)-$(PreReleaseVersionLabel).*
- 10.4
- $(FSPackageMajorVersion).3
+ 10.5
+ $(FSPackageMajorVersion).0
$(FSPackageVersion)
$(FSPackageVersion).0
16
- 0
+ 2
$(VSMajorVersion).0
$(VSMajorVersion).$(VSMinorVersion).0
$(VSAssemblyVersionPrefix).0
@@ -44,21 +44,6 @@
$(VersionPrefix).0
-
-
- <_BuildNumber>$(OfficialBuildId)
- <_BuildNumber Condition="'$(OfficialBuildId)' == ''">$([System.DateTime]::Now.ToString(yyyyMMdd)).0
- $(_BuildNumber.Split('.')[0])
- $(VSMajorVersion).$(VSMinorVersion).$(VsixVersionDateStampFix)
-
@@ -70,6 +55,7 @@
https://dotnet.myget.org/F/roslyn-tools/api/v3/index.json;
https://api.nuget.org/v3/index.json;
https://dotnet.myget.org/F/roslyn/api/v3/index.json;
+ https://dotnet.myget.org/F/roslyn-analyzers/api/v3/index.json;
https://dotnet.myget.org/F/symreader-converter/api/v3/index.json;
https://dotnet.myget.org/F/interactive-window/api/v3/index.json;
https://myget.org/F/vs-devcore/api/v3/index.json;
@@ -112,7 +98,10 @@
$(RoslynVersion)
$(RoslynVersion)
$(RoslynVersion)
+ $(RoslynVersion)
$(RoslynVersion)
+ $(RoslynVersion)
+ 2.0.17
$(RoslynVersion)
16.0.461
@@ -179,7 +168,8 @@
1.0.30
8.0.0-alpha
2.7.0
- 2.0.3
+ 3.0.0-preview-27318-01
+ 3.0.0-preview-27318-01
15.8.0
1.0.0
4.3.0
diff --git a/eng/build-utils.ps1 b/eng/build-utils.ps1
index efb7b761a5..772de110ca 100644
--- a/eng/build-utils.ps1
+++ b/eng/build-utils.ps1
@@ -178,7 +178,7 @@ function Get-PackageDir([string]$name, [string]$version = "") {
return $p
}
-function Run-MSBuild([string]$projectFilePath, [string]$buildArgs = "", [string]$logFileName = "", [switch]$parallel = $true, [switch]$summary = $true, [switch]$warnAsError = $true, [string]$configuration = $script:configuration) {
+function Run-MSBuild([string]$projectFilePath, [string]$buildArgs = "", [string]$logFileName = "", [switch]$parallel = $true, [switch]$summary = $true, [switch]$warnAsError = $true, [string]$configuration = $script:configuration, [string]$verbosity = $script:verbosity) {
# Because we override the C#/VB toolset to build against our LKG package, it is important
# that we do not reuse MSBuild nodes from other jobs/builds on the machine. Otherwise,
# we'll run into issues such as https://github.com/dotnet/roslyn/issues/6211.
@@ -216,10 +216,6 @@ function Run-MSBuild([string]$projectFilePath, [string]$buildArgs = "", [string]
$args += " /p:ContinuousIntegrationBuild=true"
}
- if ($bootstrapDir -ne "") {
- $args += " /p:BootstrapBuildPath=$bootstrapDir"
- }
-
$args += " $buildArgs"
$args += " $projectFilePath"
$args += " $properties"
@@ -240,10 +236,11 @@ function Make-BootstrapBuild() {
Remove-Item -re $dir -ErrorAction SilentlyContinue
Create-Directory $dir
- # prepare FsLex and Fsyacc
- Run-MSBuild "$RepoRoot\src\buildtools\buildtools.proj" "/restore /t:Build" -logFileName "BuildTools" -configuration $bootstrapConfiguration
- Copy-Item "$ArtifactsDir\bin\fslex\$bootstrapConfiguration\netcoreapp2.1\*" -Destination $dir
- Copy-Item "$ArtifactsDir\bin\fsyacc\$bootstrapConfiguration\netcoreapp2.1\*" -Destination $dir
+ # prepare FsLex and Fsyacc and AssemblyCheck
+ Run-MSBuild "$RepoRoot\src\buildtools\buildtools.proj" "/restore /t:Publish" -logFileName "BuildTools" -configuration $bootstrapConfiguration
+ Copy-Item "$ArtifactsDir\bin\fslex\$bootstrapConfiguration\netcoreapp2.1\publish" -Destination "$dir\fslex" -Force -Recurse
+ Copy-Item "$ArtifactsDir\bin\fsyacc\$bootstrapConfiguration\netcoreapp2.1\publish" -Destination "$dir\fsyacc" -Force -Recurse
+ Copy-Item "$ArtifactsDir\bin\AssemblyCheck\$bootstrapConfiguration\netcoreapp2.1\publish" -Destination "$dir\AssemblyCheck" -Force -Recurse
# prepare compiler
$projectPath = "$RepoRoot\proto.proj"
diff --git a/eng/build.sh b/eng/build.sh
index e1fa618cec..e806856c55 100755
--- a/eng/build.sh
+++ b/eng/build.sh
@@ -13,7 +13,9 @@ usage()
echo " --binaryLog Create MSBuild binary log (short: -bl)"
echo ""
echo "Actions:"
+ echo " --bootstrap Force the build of the bootstrap compiler"
echo " --restore Restore projects required to build (short: -r)"
+ echo " --norestore Don't restore projects required to build"
echo " --build Build all projects (short: -b)"
echo " --rebuild Rebuild all projects"
echo " --pack Build nuget packages"
@@ -54,6 +56,7 @@ test_core_clr=false
configuration="Debug"
verbosity='minimal'
binary_log=false
+force_bootstrap=false
ci=false
skip_analyzers=false
prepare_machine=false
@@ -88,6 +91,9 @@ while [[ $# > 0 ]]; do
--binarylog|-bl)
binary_log=true
;;
+ --bootstrap)
+ force_bootstrap=true
+ ;;
--restore|-r)
restore=true
;;
@@ -209,17 +215,33 @@ function BuildSolution {
quiet_restore=true
fi
+ # Node reuse fails because multiple different versions of FSharp.Build.dll get loaded into MSBuild nodes
+ node_reuse=false
+
# build bootstrap tools
bootstrap_config=Proto
- MSBuild "$repo_root/src/buildtools/buildtools.proj" \
- /restore \
- /p:Configuration=$bootstrap_config \
- /t:Build
-
bootstrap_dir=$artifacts_dir/Bootstrap
- mkdir -p "$bootstrap_dir"
- cp $artifacts_dir/bin/fslex/$bootstrap_config/netcoreapp2.1/* $bootstrap_dir
- cp $artifacts_dir/bin/fsyacc/$bootstrap_config/netcoreapp2.1/* $bootstrap_dir
+ if [[ "$force_bootstrap" == true ]]; then
+ rm -fr $bootstrap_dir
+ fi
+ if [ ! -f "$bootstrap_dir/fslex.dll" ]; then
+ MSBuild "$repo_root/src/buildtools/buildtools.proj" \
+ /restore \
+ /p:Configuration=$bootstrap_config \
+ /t:Publish
+
+ mkdir -p "$bootstrap_dir"
+ cp -pr $artifacts_dir/bin/fslex/$bootstrap_config/netcoreapp2.1/publish $bootstrap_dir/fslex
+ cp -pr $artifacts_dir/bin/fsyacc/$bootstrap_config/netcoreapp2.1/publish $bootstrap_dir/fsyacc
+ fi
+ if [ ! -f "$bootstrap_dir/fsc.exe" ]; then
+ MSBuild "$repo_root/proto.proj" \
+ /restore \
+ /p:Configuration=$bootstrap_config \
+ /t:Publish
+
+ cp -pr $artifacts_dir/bin/fsc/$bootstrap_config/netcoreapp2.1/publish $bootstrap_dir/fsc
+ fi
# do real build
MSBuild $toolset_build_proj \
@@ -247,7 +269,7 @@ InstallDotNetSdk $_InitializeDotNetCli 2.1.503
BuildSolution
if [[ "$test_core_clr" == true ]]; then
- coreclrtestframework=netcoreapp2.1
+ coreclrtestframework=netcoreapp3.0
TestUsingNUnit --testproject "$repo_root/tests/FSharp.Compiler.UnitTests/FSharp.Compiler.UnitTests.fsproj" --targetframework $coreclrtestframework
TestUsingNUnit --testproject "$repo_root/tests/FSharp.Compiler.LanguageServer.UnitTests/FSharp.Compiler.LanguageServer.UnitTests.fsproj" --targetframework $coreclrtestframework
TestUsingNUnit --testproject "$repo_root/tests/FSharp.Build.UnitTests/FSharp.Build.UnitTests.fsproj" --targetframework $coreclrtestframework
diff --git a/eng/common/SigningValidation.proj b/eng/common/SigningValidation.proj
index 7045fb6fb9..3d0ac80af3 100644
--- a/eng/common/SigningValidation.proj
+++ b/eng/common/SigningValidation.proj
@@ -3,7 +3,7 @@
+
+
+ $(WorkItemDirectory)
+ $(WorkItemCommand) --bdn-arguments="--anyCategories $(BDNCategories) $(ExtraBenchmarkDotNetArguments) $(CoreRunArgument) --artifacts $(ArtifactsDirectory) --partition-count $(PartitionCount) --partition-index %(HelixWorkItem.Index)"
+ 4:00
+
+
+
+
+ $(WorkItemDirectory)
+ $(WorkItemCommand) --bdn-arguments="--anyCategories $(BDNCategories) $(ExtraBenchmarkDotNetArguments) $(CoreRunArgument) --artifacts $(ArtifactsDirectory)"
+ 4:00
+
+
+
\ No newline at end of file
diff --git a/eng/common/performance/performance-setup.ps1 b/eng/common/performance/performance-setup.ps1
new file mode 100644
index 0000000000..7e5441f797
--- /dev/null
+++ b/eng/common/performance/performance-setup.ps1
@@ -0,0 +1,91 @@
+Param(
+ [string] $SourceDirectory=$env:BUILD_SOURCESDIRECTORY,
+ [string] $CoreRootDirectory,
+ [string] $Architecture="x64",
+ [string] $Framework="netcoreapp3.0",
+ [string] $CompilationMode="Tiered",
+ [string] $Repository=$env:BUILD_REPOSITORY_NAME,
+ [string] $Branch=$env:BUILD_SOURCEBRANCH,
+ [string] $CommitSha=$env:BUILD_SOURCEVERSION,
+ [string] $BuildNumber=$env:BUILD_BUILDNUMBER,
+ [string] $RunCategories="coreclr corefx",
+ [string] $Csproj="src\benchmarks\micro\MicroBenchmarks.csproj",
+ [string] $Kind="micro",
+ [switch] $Internal,
+ [string] $Configurations="CompilationMode=$CompilationMode"
+)
+
+$RunFromPerformanceRepo = ($Repository -eq "dotnet/performance")
+$UseCoreRun = ($CoreRootDirectory -ne [string]::Empty)
+
+$PayloadDirectory = (Join-Path $SourceDirectory "Payload")
+$PerformanceDirectory = (Join-Path $PayloadDirectory "performance")
+$WorkItemDirectory = (Join-Path $SourceDirectory "workitem")
+$ExtraBenchmarkDotNetArguments = "--iterationCount 1 --warmupCount 0 --invocationCount 1 --unrollFactor 1 --strategy ColdStart --stopOnFirstError true"
+$Creator = $env:BUILD_DEFINITIONNAME
+$PerfLabArguments = ""
+$HelixSourcePrefix = "pr"
+
+$Queue = "Windows.10.Amd64.ClientRS4.DevEx.15.8.Open"
+
+if ($Framework.StartsWith("netcoreapp")) {
+ $Queue = "Windows.10.Amd64.ClientRS4.Open"
+}
+
+if ($Internal) {
+ $Queue = "Windows.10.Amd64.ClientRS5.Perf"
+ $PerfLabArguments = "--upload-to-perflab-container"
+ $ExtraBenchmarkDotNetArguments = ""
+ $Creator = ""
+ $HelixSourcePrefix = "official"
+}
+
+$CommonSetupArguments="--frameworks $Framework --queue $Queue --build-number $BuildNumber --build-configs $Configurations"
+$SetupArguments = "--repository https://github.com/$Repository --branch $Branch --get-perf-hash --commit-sha $CommitSha $CommonSetupArguments"
+
+if ($RunFromPerformanceRepo) {
+ $SetupArguments = "--perf-hash $CommitSha $CommonSetupArguments"
+
+ robocopy $SourceDirectory $PerformanceDirectory /E /XD $PayloadDirectory $SourceDirectory\artifacts $SourceDirectory\.git
+}
+else {
+ git clone --branch master --depth 1 --quiet https://github.com/dotnet/performance $PerformanceDirectory
+}
+
+if ($UseCoreRun) {
+ $NewCoreRoot = (Join-Path $PayloadDirectory "Core_Root")
+ Move-Item -Path $CoreRootDirectory -Destination $NewCoreRoot
+}
+
+$DocsDir = (Join-Path $PerformanceDirectory "docs")
+robocopy $DocsDir $WorkItemDirectory
+
+# Set variables that we will need to have in future steps
+$ci = $true
+
+. "$PSScriptRoot\..\pipeline-logging-functions.ps1"
+
+# Directories
+Write-PipelineSetVariable -Name 'PayloadDirectory' -Value "$PayloadDirectory" -IsMultiJobVariable $false
+Write-PipelineSetVariable -Name 'PerformanceDirectory' -Value "$PerformanceDirectory" -IsMultiJobVariable $false
+Write-PipelineSetVariable -Name 'WorkItemDirectory' -Value "$WorkItemDirectory" -IsMultiJobVariable $false
+
+# Script Arguments
+Write-PipelineSetVariable -Name 'Python' -Value "py -3" -IsMultiJobVariable $false
+Write-PipelineSetVariable -Name 'ExtraBenchmarkDotNetArguments' -Value "$ExtraBenchmarkDotNetArguments" -IsMultiJobVariable $false
+Write-PipelineSetVariable -Name 'SetupArguments' -Value "$SetupArguments" -IsMultiJobVariable $false
+Write-PipelineSetVariable -Name 'PerfLabArguments' -Value "$PerfLabArguments" -IsMultiJobVariable $false
+Write-PipelineSetVariable -Name 'BDNCategories' -Value "$RunCategories" -IsMultiJobVariable $false
+Write-PipelineSetVariable -Name 'TargetCsproj' -Value "$Csproj" -IsMultiJobVariable $false
+Write-PipelineSetVariable -Name 'Kind' -Value "$Kind" -IsMultiJobVariable $false
+Write-PipelineSetVariable -Name 'Architecture' -Value "$Architecture" -IsMultiJobVariable $false
+Write-PipelineSetVariable -Name 'UseCoreRun' -Value "$UseCoreRun" -IsMultiJobVariable $false
+Write-PipelineSetVariable -Name 'RunFromPerfRepo' -Value "$RunFromPerformanceRepo" -IsMultiJobVariable $false
+
+# Helix Arguments
+Write-PipelineSetVariable -Name 'Creator' -Value "$Creator" -IsMultiJobVariable $false
+Write-PipelineSetVariable -Name 'Queue' -Value "$Queue" -IsMultiJobVariable $false
+Write-PipelineSetVariable -Name 'HelixSourcePrefix' -Value "$HelixSourcePrefix" -IsMultiJobVariable $false
+Write-PipelineSetVariable -Name '_BuildConfig' -Value "$Architecture.$Kind.$Framework" -IsMultiJobVariable $false
+
+exit 0
\ No newline at end of file
diff --git a/eng/common/performance/performance-setup.sh b/eng/common/performance/performance-setup.sh
new file mode 100755
index 0000000000..126da5f76d
--- /dev/null
+++ b/eng/common/performance/performance-setup.sh
@@ -0,0 +1,176 @@
+#!/usr/bin/env bash
+
+source_directory=$BUILD_SOURCESDIRECTORY
+core_root_directory=
+architecture=x64
+framework=netcoreapp3.0
+compilation_mode=tiered
+repository=$BUILD_REPOSITORY_NAME
+branch=$BUILD_SOURCEBRANCH
+commit_sha=$BUILD_SOURCEVERSION
+build_number=$BUILD_BUILDNUMBER
+internal=false
+kind="micro"
+run_categories="coreclr corefx"
+csproj="src\benchmarks\micro\MicroBenchmarks.csproj"
+configurations=
+run_from_perf_repo=false
+use_core_run=true
+
+while (($# > 0)); do
+ lowerI="$(echo $1 | awk '{print tolower($0)}')"
+ case $lowerI in
+ --sourcedirectory)
+ source_directory=$2
+ shift 2
+ ;;
+ --corerootdirectory)
+ core_root_directory=$2
+ shift 2
+ ;;
+ --architecture)
+ architecture=$2
+ shift 2
+ ;;
+ --framework)
+ framework=$2
+ shift 2
+ ;;
+ --compilationmode)
+ compilation_mode=$2
+ shift 2
+ ;;
+ --repository)
+ repository=$2
+ shift 2
+ ;;
+ --branch)
+ branch=$2
+ shift 2
+ ;;
+ --commitsha)
+ commit_sha=$2
+ shift 2
+ ;;
+ --buildnumber)
+ build_number=$2
+ shift 2
+ ;;
+ --kind)
+ kind=$2
+ shift 2
+ ;;
+ --runcategories)
+ run_categories=$2
+ shift 2
+ ;;
+ --csproj)
+ csproj=$2
+ shift 2
+ ;;
+ --internal)
+ internal=true
+ shift 1
+ ;;
+ --configurations)
+ configurations=$2
+ shift 2
+ ;;
+ --help)
+ echo "Common settings:"
+ echo " --corerootdirectory Directory where Core_Root exists, if running perf testing with --corerun"
+ echo " --architecture Architecture of the testing being run"
+ echo " --configurations List of key=value pairs that will be passed to perf testing infrastructure."
+ echo " ex: --configurations \"CompilationMode=Tiered OptimzationLevel=PGO\""
+ echo " --help Print help and exit"
+ echo ""
+ echo "Advanced settings:"
+ echo " --framework The framework to run, if not running in master"
+ echo " --compliationmode The compilation mode if not passing --configurations"
+ echo " --sourcedirectory The directory of the sources. Defaults to env:BUILD_SOURCESDIRECTORY"
+ echo " --repository The name of the repository in the / format. Defaults to env:BUILD_REPOSITORY_NAME"
+ echo " --branch The name of the branch. Defaults to env:BUILD_SOURCEBRANCH"
+ echo " --commitsha The commit sha1 to run against. Defaults to env:BUILD_SOURCEVERSION"
+ echo " --buildnumber The build number currently running. Defaults to env:BUILD_BUILDNUMBER"
+ echo " --csproj The relative path to the benchmark csproj whose tests should be run. Defaults to src\benchmarks\micro\MicroBenchmarks.csproj"
+ echo " --kind Related to csproj. The kind of benchmarks that should be run. Defaults to micro"
+ echo " --runcategories Related to csproj. Categories of benchmarks to run. Defaults to \"coreclr corefx\""
+ echo " --internal If the benchmarks are running as an official job."
+ echo ""
+ exit 0
+ ;;
+ esac
+done
+
+if [[ "$repository" == "dotnet/performance" ]]; then
+ run_from_perf_repo=true
+fi
+
+if [ -z "$configurations" ]; then
+ configurations="CompliationMode=$compilation_mode"
+fi
+
+if [ -z "$core_root_directory" ]; then
+ use_core_run=false
+fi
+
+payload_directory=$source_directory/Payload
+performance_directory=$payload_directory/performance
+workitem_directory=$source_directory/workitem
+extra_benchmark_dotnet_arguments="--iterationCount 1 --warmupCount 0 --invocationCount 1 --unrollFactor 1 --strategy ColdStart --stopOnFirstError true"
+perflab_arguments=
+queue=Ubuntu.1804.Amd64.Open
+creator=$BUILD_DEFINITIONNAME
+helix_source_prefix="pr"
+
+if [[ "$internal" == true ]]; then
+ perflab_arguments="--upload-to-perflab-container"
+ helix_source_prefix="official"
+ creator=
+ extra_benchmark_dotnet_arguments=
+
+ if [[ "$architecture" = "arm64" ]]; then
+ queue=Ubuntu.1804.Arm64.Perf
+ else
+ queue=Ubuntu.1804.Amd64.Perf
+ fi
+fi
+
+common_setup_arguments="--frameworks $framework --queue $queue --build-number $build_number --build-configs $configurations"
+setup_arguments="--repository https://github.com/$repository --branch $branch --get-perf-hash --commit-sha $commit_sha $common_setup_arguments"
+
+if [[ "$run_from_perf_repo" = true ]]; then
+ payload_directory=
+ workitem_directory=$source_directory
+ performance_directory=$workitem_directory
+ setup_arguments="--perf-hash $commit_sha $common_setup_arguments"
+else
+ git clone --branch master --depth 1 --quiet https://github.com/dotnet/performance $performance_directory
+
+ docs_directory=$performance_directory/docs
+ mv $docs_directory $workitem_directory
+fi
+
+if [[ "$use_core_run" = true ]]; then
+ new_core_root=$payload_directory/Core_Root
+ mv $core_root_directory $new_core_root
+fi
+
+# Make sure all of our variables are available for future steps
+echo "##vso[task.setvariable variable=UseCoreRun]$use_core_run"
+echo "##vso[task.setvariable variable=Architecture]$architecture"
+echo "##vso[task.setvariable variable=PayloadDirectory]$payload_directory"
+echo "##vso[task.setvariable variable=PerformanceDirectory]$performance_directory"
+echo "##vso[task.setvariable variable=WorkItemDirectory]$workitem_directory"
+echo "##vso[task.setvariable variable=Queue]$queue"
+echo "##vso[task.setvariable variable=SetupArguments]$setup_arguments"
+echo "##vso[task.setvariable variable=Python]python3"
+echo "##vso[task.setvariable variable=PerfLabArguments]$perflab_arguments"
+echo "##vso[task.setvariable variable=ExtraBenchmarkDotNetArguments]$extra_benchmark_dotnet_arguments"
+echo "##vso[task.setvariable variable=BDNCategories]$run_categories"
+echo "##vso[task.setvariable variable=TargetCsproj]$csproj"
+echo "##vso[task.setvariable variable=RunFromPerfRepo]$run_from_perf_repo"
+echo "##vso[task.setvariable variable=Creator]$creator"
+echo "##vso[task.setvariable variable=HelixSourcePrefix]$helix_source_prefix"
+echo "##vso[task.setvariable variable=Kind]$kind"
+echo "##vso[task.setvariable variable=_BuildConfig]$architecture.$kind.$framework"
\ No newline at end of file
diff --git a/eng/common/pipeline-logging-functions.ps1 b/eng/common/pipeline-logging-functions.ps1
index 7b61376f8a..af5f48aace 100644
--- a/eng/common/pipeline-logging-functions.ps1
+++ b/eng/common/pipeline-logging-functions.ps1
@@ -77,13 +77,14 @@ function Write-PipelineTaskError {
[string]$Name,
[string]$Value,
[switch]$Secret,
- [switch]$AsOutput)
-
+ [switch]$AsOutput,
+ [bool]$IsMultiJobVariable=$true)
+
if($ci) {
Write-LoggingCommand -Area 'task' -Event 'setvariable' -Data $Value -Properties @{
'variable' = $Name
'isSecret' = $Secret
- 'isOutput' = 'true'
+ 'isOutput' = $IsMultiJobVariable
} -AsOutput:$AsOutput
}
}
diff --git a/eng/common/pipeline-logging-functions.sh b/eng/common/pipeline-logging-functions.sh
old mode 100644
new mode 100755
index 6098f9a543..1c560a5061
--- a/eng/common/pipeline-logging-functions.sh
+++ b/eng/common/pipeline-logging-functions.sh
@@ -39,11 +39,11 @@ function Write-PipelineTaskError {
return
fi
- message_type="error"
- sourcepath=''
- linenumber=''
- columnnumber=''
- error_code=''
+ local message_type="error"
+ local sourcepath=''
+ local linenumber=''
+ local columnnumber=''
+ local error_code=''
while [[ $# -gt 0 ]]; do
opt="$(echo "${1/#--/-}" | awk '{print tolower($0)}')"
@@ -76,7 +76,7 @@ function Write-PipelineTaskError {
shift
done
- message="##vso[task.logissue"
+ local message="##vso[task.logissue"
message="$message type=$message_type"
@@ -100,3 +100,73 @@ function Write-PipelineTaskError {
echo "$message"
}
+function Write-PipelineSetVariable {
+ if [[ "$ci" != true ]]; then
+ return
+ fi
+
+ local name=''
+ local value=''
+ local secret=false
+ local as_output=false
+ local is_multi_job_variable=true
+
+ while [[ $# -gt 0 ]]; do
+ opt="$(echo "${1/#--/-}" | awk '{print tolower($0)}')"
+ case "$opt" in
+ -name|-n)
+ name=$2
+ shift
+ ;;
+ -value|-v)
+ value=$2
+ shift
+ ;;
+ -secret|-s)
+ secret=true
+ ;;
+ -as_output|-a)
+ as_output=true
+ ;;
+ -is_multi_job_variable|-i)
+ is_multi_job_variable=$2
+ shift
+ ;;
+ esac
+ shift
+ done
+
+ value=${value/;/%3B}
+ value=${value/\\r/%0D}
+ value=${value/\\n/%0A}
+ value=${value/]/%5D}
+
+ local message="##vso[task.setvariable variable=$name;isSecret=$secret;isOutput=$is_multi_job_variable]$value"
+
+ if [[ "$as_output" == true ]]; then
+ $message
+ else
+ echo "$message"
+ fi
+}
+
+function Write-PipelinePrependPath {
+ local prepend_path=''
+
+ while [[ $# -gt 0 ]]; do
+ opt="$(echo "${1/#--/-}" | awk '{print tolower($0)}')"
+ case "$opt" in
+ -path|-p)
+ prepend_path=$2
+ shift
+ ;;
+ esac
+ shift
+ done
+
+ export PATH="$prepend_path:$PATH"
+
+ if [[ "$ci" == true ]]; then
+ echo "##vso[task.prependpath]$prepend_path"
+ fi
+}
\ No newline at end of file
diff --git a/eng/common/post-build/darc-gather-drop.ps1 b/eng/common/post-build/darc-gather-drop.ps1
new file mode 100644
index 0000000000..93a0bd8328
--- /dev/null
+++ b/eng/common/post-build/darc-gather-drop.ps1
@@ -0,0 +1,35 @@
+param(
+ [Parameter(Mandatory=$true)][int] $BarBuildId, # ID of the build which assets should be downloaded
+ [Parameter(Mandatory=$true)][string] $DropLocation, # Where the assets should be downloaded to
+ [Parameter(Mandatory=$true)][string] $MaestroApiAccessToken, # Token used to access Maestro API
+ [Parameter(Mandatory=$false)][string] $MaestroApiEndPoint = "https://maestro-prod.westus2.cloudapp.azure.com", # Maestro API URL
+ [Parameter(Mandatory=$false)][string] $MaestroApiVersion = "2019-01-16" # Version of Maestro API to use
+)
+
+. $PSScriptRoot\post-build-utils.ps1
+
+try {
+ Write-Host "Installing DARC ..."
+
+ . $PSScriptRoot\..\darc-init.ps1
+ $exitCode = $LASTEXITCODE
+
+ if ($exitCode -ne 0) {
+ Write-PipelineTaskError "Something failed while running 'darc-init.ps1'. Check for errors above. Exiting now..."
+ ExitWithExitCode $exitCode
+ }
+
+ darc gather-drop --non-shipping `
+ --continue-on-error `
+ --id $BarBuildId `
+ --output-dir $DropLocation `
+ --bar-uri $MaestroApiEndpoint `
+ --password $MaestroApiAccessToken `
+ --latest-location
+}
+catch {
+ Write-Host $_
+ Write-Host $_.Exception
+ Write-Host $_.ScriptStackTrace
+ ExitWithExitCode 1
+}
diff --git a/eng/common/post-build/nuget-validation.ps1 b/eng/common/post-build/nuget-validation.ps1
new file mode 100644
index 0000000000..78ed0d540f
--- /dev/null
+++ b/eng/common/post-build/nuget-validation.ps1
@@ -0,0 +1,25 @@
+# This script validates NuGet package metadata information using this
+# tool: https://github.com/NuGet/NuGetGallery/tree/jver-verify/src/VerifyMicrosoftPackage
+
+param(
+ [Parameter(Mandatory=$true)][string] $PackagesPath, # Path to where the packages to be validated are
+ [Parameter(Mandatory=$true)][string] $ToolDestinationPath # Where the validation tool should be downloaded to
+)
+
+. $PSScriptRoot\post-build-utils.ps1
+
+try {
+ $url = "https://raw.githubusercontent.com/NuGet/NuGetGallery/jver-verify/src/VerifyMicrosoftPackage/verify.ps1"
+
+ New-Item -ItemType "directory" -Path ${ToolDestinationPath} -Force
+
+ Invoke-WebRequest $url -OutFile ${ToolDestinationPath}\verify.ps1
+
+ & ${ToolDestinationPath}\verify.ps1 ${PackagesPath}\*.nupkg
+}
+catch {
+ Write-PipelineTaskError "NuGet package validation failed. Please check error logs."
+ Write-Host $_
+ Write-Host $_.ScriptStackTrace
+ ExitWithExitCode 1
+}
diff --git a/eng/common/post-build/post-build-utils.ps1 b/eng/common/post-build/post-build-utils.ps1
new file mode 100644
index 0000000000..551ae113f8
--- /dev/null
+++ b/eng/common/post-build/post-build-utils.ps1
@@ -0,0 +1,90 @@
+# Most of the functions in this file require the variables `MaestroApiEndPoint`,
+# `MaestroApiVersion` and `MaestroApiAccessToken` to be globally available.
+
+$ErrorActionPreference = "Stop"
+Set-StrictMode -Version 2.0
+
+# `tools.ps1` checks $ci to perform some actions. Since the post-build
+# scripts don't necessarily execute in the same agent that run the
+# build.ps1/sh script this variable isn't automatically set.
+$ci = $true
+. $PSScriptRoot\..\tools.ps1
+
+function Create-MaestroApiRequestHeaders([string]$ContentType = "application/json") {
+ Validate-MaestroVars
+
+ $headers = New-Object 'System.Collections.Generic.Dictionary[[String],[String]]'
+ $headers.Add('Accept', $ContentType)
+ $headers.Add('Authorization',"Bearer $MaestroApiAccessToken")
+ return $headers
+}
+
+function Get-MaestroChannel([int]$ChannelId) {
+ Validate-MaestroVars
+
+ $apiHeaders = Create-MaestroApiRequestHeaders
+ $apiEndpoint = "$MaestroApiEndPoint/api/channels/${ChannelId}?api-version=$MaestroApiVersion"
+
+ $result = try { Invoke-WebRequest -Method Get -Uri $apiEndpoint -Headers $apiHeaders | ConvertFrom-Json } catch { Write-Host "Error: $_" }
+ return $result
+}
+
+function Get-MaestroBuild([int]$BuildId) {
+ Validate-MaestroVars
+
+ $apiHeaders = Create-MaestroApiRequestHeaders -AuthToken $MaestroApiAccessToken
+ $apiEndpoint = "$MaestroApiEndPoint/api/builds/${BuildId}?api-version=$MaestroApiVersion"
+
+ $result = try { return Invoke-WebRequest -Method Get -Uri $apiEndpoint -Headers $apiHeaders | ConvertFrom-Json } catch { Write-Host "Error: $_" }
+ return $result
+}
+
+function Get-MaestroSubscriptions([string]$SourceRepository, [int]$ChannelId) {
+ Validate-MaestroVars
+
+ $SourceRepository = [System.Web.HttpUtility]::UrlEncode($SourceRepository)
+ $apiHeaders = Create-MaestroApiRequestHeaders -AuthToken $MaestroApiAccessToken
+ $apiEndpoint = "$MaestroApiEndPoint/api/subscriptions?sourceRepository=$SourceRepository&channelId=$ChannelId&api-version=$MaestroApiVersion"
+
+ $result = try { Invoke-WebRequest -Method Get -Uri $apiEndpoint -Headers $apiHeaders | ConvertFrom-Json } catch { Write-Host "Error: $_" }
+ return $result
+}
+
+function Trigger-Subscription([string]$SubscriptionId) {
+ Validate-MaestroVars
+
+ $apiHeaders = Create-MaestroApiRequestHeaders -AuthToken $MaestroApiAccessToken
+ $apiEndpoint = "$MaestroApiEndPoint/api/subscriptions/$SubscriptionId/trigger?api-version=$MaestroApiVersion"
+ Invoke-WebRequest -Uri $apiEndpoint -Headers $apiHeaders -Method Post | Out-Null
+}
+
+function Assign-BuildToChannel([int]$BuildId, [int]$ChannelId) {
+ Validate-MaestroVars
+
+ $apiHeaders = Create-MaestroApiRequestHeaders -AuthToken $MaestroApiAccessToken
+ $apiEndpoint = "$MaestroApiEndPoint/api/channels/${ChannelId}/builds/${BuildId}?api-version=$MaestroApiVersion"
+ Invoke-WebRequest -Method Post -Uri $apiEndpoint -Headers $apiHeaders | Out-Null
+}
+
+function Validate-MaestroVars {
+ try {
+ Get-Variable MaestroApiEndPoint -Scope Global | Out-Null
+ Get-Variable MaestroApiVersion -Scope Global | Out-Null
+ Get-Variable MaestroApiAccessToken -Scope Global | Out-Null
+
+ if (!($MaestroApiEndPoint -Match "^http[s]?://maestro-(int|prod).westus2.cloudapp.azure.com$")) {
+ Write-PipelineTaskError "MaestroApiEndPoint is not a valid Maestro URL. '$MaestroApiEndPoint'"
+ ExitWithExitCode 1
+ }
+
+ if (!($MaestroApiVersion -Match "^[0-9]{4}-[0-9]{2}-[0-9]{2}$")) {
+ Write-PipelineTaskError "MaestroApiVersion does not match a version string in the format yyyy-MM-DD. '$MaestroApiVersion'"
+ ExitWithExitCode 1
+ }
+ }
+ catch {
+ Write-PipelineTaskError "Error: Variables `MaestroApiEndPoint`, `MaestroApiVersion` and `MaestroApiAccessToken` are required while using this script."
+ Write-Host $_
+ ExitWithExitCode 1
+ }
+}
diff --git a/eng/common/post-build/promote-build.ps1 b/eng/common/post-build/promote-build.ps1
new file mode 100644
index 0000000000..e5ae85f251
--- /dev/null
+++ b/eng/common/post-build/promote-build.ps1
@@ -0,0 +1,48 @@
+param(
+ [Parameter(Mandatory=$true)][int] $BuildId,
+ [Parameter(Mandatory=$true)][int] $ChannelId,
+ [Parameter(Mandatory=$true)][string] $MaestroApiAccessToken,
+ [Parameter(Mandatory=$false)][string] $MaestroApiEndPoint = "https://maestro-prod.westus2.cloudapp.azure.com",
+ [Parameter(Mandatory=$false)][string] $MaestroApiVersion = "2019-01-16"
+)
+
+. $PSScriptRoot\post-build-utils.ps1
+
+try {
+ # Check that the channel we are going to promote the build to exist
+ $channelInfo = Get-MaestroChannel -ChannelId $ChannelId
+
+ if (!$channelInfo) {
+ Write-Host "Channel with BAR ID $ChannelId was not found in BAR!"
+ ExitWithExitCode 1
+ }
+
+ # Get info about which channels the build has already been promoted to
+ $buildInfo = Get-MaestroBuild -BuildId $BuildId
+
+ if (!$buildInfo) {
+ Write-Host "Build with BAR ID $BuildId was not found in BAR!"
+ ExitWithExitCode 1
+ }
+
+ # Find whether the build is already assigned to the channel or not
+ if ($buildInfo.channels) {
+ foreach ($channel in $buildInfo.channels) {
+ if ($channel.Id -eq $ChannelId) {
+ Write-Host "The build with BAR ID $BuildId is already on channel $ChannelId!"
+ ExitWithExitCode 0
+ }
+ }
+ }
+
+ Write-Host "Promoting build '$BuildId' to channel '$ChannelId'."
+
+ Assign-BuildToChannel -BuildId $BuildId -ChannelId $ChannelId
+
+ Write-Host "done."
+}
+catch {
+ Write-Host "There was an error while trying to promote build '$BuildId' to channel '$ChannelId'"
+ Write-Host $_
+ Write-Host $_.ScriptStackTrace
+}
diff --git a/eng/common/post-build/setup-maestro-vars.ps1 b/eng/common/post-build/setup-maestro-vars.ps1
new file mode 100644
index 0000000000..d7f64dc63c
--- /dev/null
+++ b/eng/common/post-build/setup-maestro-vars.ps1
@@ -0,0 +1,26 @@
+param(
+ [Parameter(Mandatory=$true)][string] $ReleaseConfigsPath # Full path to ReleaseConfigs.txt asset
+)
+
+. $PSScriptRoot\post-build-utils.ps1
+
+try {
+ $Content = Get-Content $ReleaseConfigsPath
+
+ $BarId = $Content | Select -Index 0
+
+ $Channels = ""
+ $Content | Select -Index 1 | ForEach-Object { $Channels += "$_ ," }
+
+ $IsStableBuild = $Content | Select -Index 2
+
+ Write-PipelineSetVariable -Name 'BARBuildId' -Value $BarId
+ Write-PipelineSetVariable -Name 'InitialChannels' -Value "$Channels"
+ Write-PipelineSetVariable -Name 'IsStableBuild' -Value $IsStableBuild
+}
+catch {
+ Write-Host $_
+ Write-Host $_.Exception
+ Write-Host $_.ScriptStackTrace
+ ExitWithExitCode 1
+}
diff --git a/eng/common/post-build/sourcelink-validation.ps1 b/eng/common/post-build/sourcelink-validation.ps1
index 84c97df1fc..41e01ae6e6 100644
--- a/eng/common/post-build/sourcelink-validation.ps1
+++ b/eng/common/post-build/sourcelink-validation.ps1
@@ -6,18 +6,15 @@ param(
[Parameter(Mandatory=$true)][string] $SourcelinkCliVersion # Version of SourceLink CLI to use
)
-$ErrorActionPreference = "Stop"
-Set-StrictMode -Version 2.0
+. $PSScriptRoot\post-build-utils.ps1
-. $PSScriptRoot\..\tools.ps1
-
-# Cache/HashMap (File -> Exist flag) used to consult whether a file exist
+# Cache/HashMap (File -> Exist flag) used to consult whether a file exist
# in the repository at a specific commit point. This is populated by inserting
# all files present in the repo at a specific commit point.
$global:RepoFiles = @{}
$ValidatePackage = {
- param(
+ param(
[string] $PackagePath # Full path to a Symbols.NuGet package
)
@@ -32,7 +29,7 @@ $ValidatePackage = {
# Extensions for which we'll look for SourceLink information
# For now we'll only care about Portable & Embedded PDBs
$RelevantExtensions = @(".dll", ".exe", ".pdb")
-
+
Write-Host -NoNewLine "Validating" ([System.IO.Path]::GetFileName($PackagePath)) "... "
$PackageId = [System.IO.Path]::GetFileNameWithoutExtension($PackagePath)
@@ -46,13 +43,13 @@ $ValidatePackage = {
try {
$zip = [System.IO.Compression.ZipFile]::OpenRead($PackagePath)
- $zip.Entries |
+ $zip.Entries |
Where-Object {$RelevantExtensions -contains [System.IO.Path]::GetExtension($_.Name)} |
ForEach-Object {
$FileName = $_.FullName
$Extension = [System.IO.Path]::GetExtension($_.Name)
$FakeName = -Join((New-Guid), $Extension)
- $TargetFile = Join-Path -Path $ExtractPath -ChildPath $FakeName
+ $TargetFile = Join-Path -Path $ExtractPath -ChildPath $FakeName
# We ignore resource DLLs
if ($FileName.EndsWith(".resources.dll")) {
@@ -62,7 +59,7 @@ $ValidatePackage = {
[System.IO.Compression.ZipFileExtensions]::ExtractToFile($_, $TargetFile, $true)
$ValidateFile = {
- param(
+ param(
[string] $FullPath, # Full path to the module that has to be checked
[string] $RealPath,
[ref] $FailedFiles
@@ -83,7 +80,7 @@ $ValidatePackage = {
ForEach-Object {
$Link = $_
$CommitUrl = "https://raw.githubusercontent.com/${using:GHRepoName}/${using:GHCommit}/"
-
+
$FilePath = $Link.Replace($CommitUrl, "")
$Status = 200
$Cache = $using:RepoFiles
@@ -91,7 +88,7 @@ $ValidatePackage = {
if ( !($Cache.ContainsKey($FilePath)) ) {
try {
$Uri = $Link -as [System.URI]
-
+
# Only GitHub links are valid
if ($Uri.AbsoluteURI -ne $null -and ($Uri.Host -match "github" -or $Uri.Host -match "githubusercontent")) {
$Status = (Invoke-WebRequest -Uri $Link -UseBasicParsing -Method HEAD -TimeoutSec 5).StatusCode
@@ -128,15 +125,15 @@ $ValidatePackage = {
}
}
}
-
+
&$ValidateFile $TargetFile $FileName ([ref]$FailedFiles)
}
}
catch {
-
+
}
finally {
- $zip.Dispose()
+ $zip.Dispose()
}
if ($FailedFiles -eq 0) {
@@ -163,13 +160,13 @@ function ValidateSourceLinkLinks {
ExitWithExitCode 1
}
- $RepoTreeURL = -Join("https://api.github.com/repos/", $GHRepoName, "/git/trees/", $GHCommit, "?recursive=1")
+ $RepoTreeURL = -Join("http://api.github.com/repos/", $GHRepoName, "/git/trees/", $GHCommit, "?recursive=1")
$CodeExtensions = @(".cs", ".vb", ".fs", ".fsi", ".fsx", ".fsscript")
try {
# Retrieve the list of files in the repo at that particular commit point and store them in the RepoFiles hash
$Data = Invoke-WebRequest $RepoTreeURL -UseBasicParsing | ConvertFrom-Json | Select-Object -ExpandProperty tree
-
+
foreach ($file in $Data) {
$Extension = [System.IO.Path]::GetExtension($file.path)
@@ -183,7 +180,7 @@ function ValidateSourceLinkLinks {
Write-Host $_
ExitWithExitCode 1
}
-
+
if (Test-Path $ExtractPath) {
Remove-Item $ExtractPath -Force -Recurse -ErrorAction SilentlyContinue
}
@@ -200,21 +197,27 @@ function ValidateSourceLinkLinks {
}
}
-function CheckExitCode ([string]$stage) {
- $exitCode = $LASTEXITCODE
- if ($exitCode -ne 0) {
- Write-PipelineTaskError "Something failed while '$stage'. Check for errors above. Exiting now..."
- ExitWithExitCode $exitCode
+function InstallSourcelinkCli {
+ $sourcelinkCliPackageName = "sourcelink"
+
+ $dotnetRoot = InitializeDotNetCli -install:$true
+ $dotnet = "$dotnetRoot\dotnet.exe"
+ $toolList = & "$dotnet" tool list --global
+
+ if (($toolList -like "*$sourcelinkCliPackageName*") -and ($toolList -like "*$sourcelinkCliVersion*")) {
+ Write-Host "SourceLink CLI version $sourcelinkCliVersion is already installed."
+ }
+ else {
+ Write-Host "Installing SourceLink CLI version $sourcelinkCliVersion..."
+ Write-Host "You may need to restart your command window if this is the first dotnet tool you have installed."
+ & "$dotnet" tool install $sourcelinkCliPackageName --version $sourcelinkCliVersion --verbosity "minimal" --global
}
}
try {
- Write-Host "Installing SourceLink CLI..."
- Get-Location
- . $PSScriptRoot\sourcelink-cli-init.ps1 -sourcelinkCliVersion $SourcelinkCliVersion
- CheckExitCode "Running sourcelink-cli-init"
+ InstallSourcelinkCli
- Measure-Command { ValidateSourceLinkLinks }
+ ValidateSourceLinkLinks
}
catch {
Write-Host $_
diff --git a/eng/common/post-build/symbols-validation.ps1 b/eng/common/post-build/symbols-validation.ps1
index 69456854e0..d5ec51b150 100644
--- a/eng/common/post-build/symbols-validation.ps1
+++ b/eng/common/post-build/symbols-validation.ps1
@@ -4,10 +4,7 @@ param(
[Parameter(Mandatory=$true)][string] $DotnetSymbolVersion # Version of dotnet symbol to use
)
-$ErrorActionPreference = "Stop"
-Set-StrictMode -Version 2.0
-
-. $PSScriptRoot\..\tools.ps1
+. $PSScriptRoot\post-build-utils.ps1
Add-Type -AssemblyName System.IO.Compression.FileSystem
@@ -162,19 +159,25 @@ function CheckSymbolsAvailable {
}
}
-function CheckExitCode ([string]$stage) {
- $exitCode = $LASTEXITCODE
- if ($exitCode -ne 0) {
- Write-PipelineTaskError "Something failed while '$stage'. Check for errors above. Exiting now..."
- ExitWithExitCode $exitCode
+function Installdotnetsymbol {
+ $dotnetsymbolPackageName = "dotnet-symbol"
+
+ $dotnetRoot = InitializeDotNetCli -install:$true
+ $dotnet = "$dotnetRoot\dotnet.exe"
+ $toolList = & "$dotnet" tool list --global
+
+ if (($toolList -like "*$dotnetsymbolPackageName*") -and ($toolList -like "*$dotnetsymbolVersion*")) {
+ Write-Host "dotnet-symbol version $dotnetsymbolVersion is already installed."
+ }
+ else {
+ Write-Host "Installing dotnet-symbol version $dotnetsymbolVersion..."
+ Write-Host "You may need to restart your command window if this is the first dotnet tool you have installed."
+ & "$dotnet" tool install $dotnetsymbolPackageName --version $dotnetsymbolVersion --verbosity "minimal" --global
}
}
try {
- Write-Host "Installing dotnet symbol ..."
- Get-Location
- . $PSScriptRoot\dotnetsymbol-init.ps1 -dotnetsymbolVersion $DotnetSymbolVersion
- CheckExitCode "Running dotnetsymbol-init"
+ Installdotnetsymbol
CheckSymbolsAvailable
}
diff --git a/eng/common/post-build/trigger-subscriptions.ps1 b/eng/common/post-build/trigger-subscriptions.ps1
new file mode 100644
index 0000000000..926d5b4551
--- /dev/null
+++ b/eng/common/post-build/trigger-subscriptions.ps1
@@ -0,0 +1,57 @@
+param(
+ [Parameter(Mandatory=$true)][string] $SourceRepo,
+ [Parameter(Mandatory=$true)][int] $ChannelId,
+ [Parameter(Mandatory=$true)][string] $MaestroApiAccessToken,
+ [Parameter(Mandatory=$false)][string] $MaestroApiEndPoint = "https://maestro-prod.westus2.cloudapp.azure.com",
+ [Parameter(Mandatory=$false)][string] $MaestroApiVersion = "2019-01-16"
+)
+
+. $PSScriptRoot\post-build-utils.ps1
+
+# Get all the $SourceRepo subscriptions
+$normalizedSourceRepo = $SourceRepo.Replace('dnceng@', '')
+$subscriptions = Get-MaestroSubscriptions -SourceRepository $normalizedSourceRepo -ChannelId $ChannelId
+
+if (!$subscriptions) {
+ Write-Host "No subscriptions found for source repo '$normalizedSourceRepo' in channel '$ChannelId'"
+ ExitWithExitCode 0
+}
+
+$subscriptionsToTrigger = New-Object System.Collections.Generic.List[string]
+$failedTriggeredSubscription = $false
+
+# Get all enabled subscriptions that need dependency flow on 'everyBuild'
+foreach ($subscription in $subscriptions) {
+ if ($subscription.enabled -and $subscription.policy.updateFrequency -like 'everyBuild' -and $subscription.channel.id -eq $ChannelId) {
+ Write-Host "Should trigger this subscription: $subscription.id"
+ [void]$subscriptionsToTrigger.Add($subscription.id)
+ }
+}
+
+foreach ($subscriptionToTrigger in $subscriptionsToTrigger) {
+ try {
+ Write-Host "Triggering subscription '$subscriptionToTrigger'."
+
+ Trigger-Subscription -SubscriptionId $subscriptionToTrigger
+
+ Write-Host "done."
+ }
+ catch
+ {
+ Write-Host "There was an error while triggering subscription '$subscriptionToTrigger'"
+ Write-Host $_
+ Write-Host $_.ScriptStackTrace
+ $failedTriggeredSubscription = $true
+ }
+}
+
+if ($subscriptionsToTrigger.Count -eq 0) {
+ Write-Host "No subscription matched source repo '$normalizedSourceRepo' and channel ID '$ChannelId'."
+}
+elseif ($failedTriggeredSubscription) {
+ Write-Host "At least one subscription failed to be triggered..."
+ ExitWithExitCode 1
+}
+else {
+ Write-Host "All subscriptions were triggered successfully!"
+}
diff --git a/eng/common/sdl/execute-all-sdl-tools.ps1 b/eng/common/sdl/execute-all-sdl-tools.ps1
index 0635f26fb6..aab7589f2c 100644
--- a/eng/common/sdl/execute-all-sdl-tools.ps1
+++ b/eng/common/sdl/execute-all-sdl-tools.ps1
@@ -22,7 +22,9 @@ Param(
[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
+ [string] $GuardianLoggerLevel="Standard", # Optional: the logger level for the Guardian CLI; options are Trace, Verbose, Standard, Warning, and Error
+ [string[]] $CrScanAdditionalRunConfigParams, # Optional: Additional Params to custom build a CredScan run config in the format @("xyz:abc","sdf:1")
+ [string[]] $PoliCheckAdditionalRunConfigParams # Optional: Additional Params to custom build a Policheck run config in the format @("xyz:abc","sdf:1")
)
$ErrorActionPreference = "Stop"
@@ -69,10 +71,10 @@ if ($TsaOnboard) {
}
if ($ArtifactToolsList -and $ArtifactToolsList.Count -gt 0) {
- & $(Join-Path $PSScriptRoot "run-sdl.ps1") -GuardianCliLocation $guardianCliLocation -WorkingDirectory $ArtifactsDirectory -TargetDirectory $ArtifactsDirectory -GdnFolder $gdnFolder -ToolsList $ArtifactToolsList -AzureDevOpsAccessToken $AzureDevOpsAccessToken -UpdateBaseline $UpdateBaseline -GuardianLoggerLevel $GuardianLoggerLevel
+ & $(Join-Path $PSScriptRoot "run-sdl.ps1") -GuardianCliLocation $guardianCliLocation -WorkingDirectory $ArtifactsDirectory -TargetDirectory $ArtifactsDirectory -GdnFolder $gdnFolder -ToolsList $ArtifactToolsList -AzureDevOpsAccessToken $AzureDevOpsAccessToken -UpdateBaseline $UpdateBaseline -GuardianLoggerLevel $GuardianLoggerLevel -CrScanAdditionalRunConfigParams $CrScanAdditionalRunConfigParams -PoliCheckAdditionalRunConfigParams $PoliCheckAdditionalRunConfigParams
}
if ($SourceToolsList -and $SourceToolsList.Count -gt 0) {
- & $(Join-Path $PSScriptRoot "run-sdl.ps1") -GuardianCliLocation $guardianCliLocation -WorkingDirectory $ArtifactsDirectory -TargetDirectory $SourceDirectory -GdnFolder $gdnFolder -ToolsList $SourceToolsList -AzureDevOpsAccessToken $AzureDevOpsAccessToken -UpdateBaseline $UpdateBaseline -GuardianLoggerLevel $GuardianLoggerLevel
+ & $(Join-Path $PSScriptRoot "run-sdl.ps1") -GuardianCliLocation $guardianCliLocation -WorkingDirectory $ArtifactsDirectory -TargetDirectory $SourceDirectory -GdnFolder $gdnFolder -ToolsList $SourceToolsList -AzureDevOpsAccessToken $AzureDevOpsAccessToken -UpdateBaseline $UpdateBaseline -GuardianLoggerLevel $GuardianLoggerLevel -CrScanAdditionalRunConfigParams $CrScanAdditionalRunConfigParams -PoliCheckAdditionalRunConfigParams $PoliCheckAdditionalRunConfigParams
}
if ($UpdateBaseline) {
diff --git a/eng/common/sdl/extract-artifact-packages.ps1 b/eng/common/sdl/extract-artifact-packages.ps1
new file mode 100644
index 0000000000..1fdbb14329
--- /dev/null
+++ b/eng/common/sdl/extract-artifact-packages.ps1
@@ -0,0 +1,70 @@
+param(
+ [Parameter(Mandatory=$true)][string] $InputPath, # Full path to directory where artifact packages are stored
+ [Parameter(Mandatory=$true)][string] $ExtractPath # Full path to directory where the packages will be extracted
+)
+
+$ErrorActionPreference = "Stop"
+Set-StrictMode -Version 2.0
+$ExtractPackage = {
+ param(
+ [string] $PackagePath # Full path to a NuGet package
+ )
+
+ if (!(Test-Path $PackagePath)) {
+ Write-PipelineTaskError "Input file does not exist: $PackagePath"
+ ExitWithExitCode 1
+ }
+
+ $RelevantExtensions = @(".dll", ".exe", ".pdb")
+ Write-Host -NoNewLine "Extracting" ([System.IO.Path]::GetFileName($PackagePath)) "... "
+
+ $PackageId = [System.IO.Path]::GetFileNameWithoutExtension($PackagePath)
+ $ExtractPath = Join-Path -Path $using:ExtractPath -ChildPath $PackageId
+
+ Add-Type -AssemblyName System.IO.Compression.FileSystem
+
+ [System.IO.Directory]::CreateDirectory($ExtractPath);
+
+ try {
+ $zip = [System.IO.Compression.ZipFile]::OpenRead($PackagePath)
+
+ $zip.Entries |
+ Where-Object {$RelevantExtensions -contains [System.IO.Path]::GetExtension($_.Name)} |
+ ForEach-Object {
+ $TargetFile = Join-Path -Path $ExtractPath -ChildPath $_.Name
+
+ [System.IO.Compression.ZipFileExtensions]::ExtractToFile($_, $TargetFile, $true)
+ }
+ }
+ catch {
+
+ }
+ finally {
+ $zip.Dispose()
+ }
+ }
+ function ExtractArtifacts {
+ if (!(Test-Path $InputPath)) {
+ Write-Host "Input Path does not exist: $InputPath"
+ ExitWithExitCode 0
+ }
+ $Jobs = @()
+ Get-ChildItem "$InputPath\*.nupkg" |
+ ForEach-Object {
+ $Jobs += Start-Job -ScriptBlock $ExtractPackage -ArgumentList $_.FullName
+ }
+
+ foreach ($Job in $Jobs) {
+ Wait-Job -Id $Job.Id | Receive-Job
+ }
+}
+
+try {
+ Measure-Command { ExtractArtifacts }
+}
+catch {
+ Write-Host $_
+ Write-Host $_.Exception
+ Write-Host $_.ScriptStackTrace
+ ExitWithExitCode 1
+}
diff --git a/eng/common/sdl/packages.config b/eng/common/sdl/packages.config
index b054737df1..3f97ac2f16 100644
--- a/eng/common/sdl/packages.config
+++ b/eng/common/sdl/packages.config
@@ -1,4 +1,4 @@
-
+
diff --git a/eng/common/sdl/run-sdl.ps1 b/eng/common/sdl/run-sdl.ps1
index e6a86d03a2..d7b8564458 100644
--- a/eng/common/sdl/run-sdl.ps1
+++ b/eng/common/sdl/run-sdl.ps1
@@ -5,7 +5,9 @@ Param(
[string] $GdnFolder,
[string[]] $ToolsList,
[string] $UpdateBaseline,
- [string] $GuardianLoggerLevel="Standard"
+ [string] $GuardianLoggerLevel="Standard",
+ [string[]] $CrScanAdditionalRunConfigParams,
+ [string[]] $PoliCheckAdditionalRunConfigParams
)
$ErrorActionPreference = "Stop"
@@ -29,8 +31,8 @@ foreach ($tool in $ToolsList) {
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 "
+ Write-Host "$GuardianCliLocation configure --working-directory $WorkingDirectory --tool $tool --output-path $gdnConfigFile --logger-level $GuardianLoggerLevel --noninteractive --force --args `" TargetDirectory : $TargetDirectory `" $(If ($CrScanAdditionalRunConfigParams) {$CrScanAdditionalRunConfigParams})"
+ & $GuardianCliLocation configure --working-directory $WorkingDirectory --tool $tool --output-path $gdnConfigFile --logger-level $GuardianLoggerLevel --noninteractive --force --args " TargetDirectory : $TargetDirectory " $(If ($CrScanAdditionalRunConfigParams) {$CrScanAdditionalRunConfigParams})
if ($LASTEXITCODE -ne 0) {
Write-Host "Guardian configure for $tool failed with exit code $LASTEXITCODE."
exit $LASTEXITCODE
@@ -38,8 +40,8 @@ foreach ($tool in $ToolsList) {
$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 "
+ Write-Host "$GuardianCliLocation configure --working-directory $WorkingDirectory --tool $tool --output-path $gdnConfigFile --logger-level $GuardianLoggerLevel --noninteractive --force --args `" Target : $TargetDirectory `" $(If ($PoliCheckAdditionalRunConfigParams) {$PoliCheckAdditionalRunConfigParams})"
+ & $GuardianCliLocation configure --working-directory $WorkingDirectory --tool $tool --output-path $gdnConfigFile --logger-level $GuardianLoggerLevel --noninteractive --force --args " Target : $TargetDirectory " $(If ($PoliCheckAdditionalRunConfigParams) {$PoliCheckAdditionalRunConfigParams})
if ($LASTEXITCODE -ne 0) {
Write-Host "Guardian configure for $tool failed with exit code $LASTEXITCODE."
exit $LASTEXITCODE
diff --git a/eng/common/templates/job/execute-sdl.yml b/eng/common/templates/job/execute-sdl.yml
index acb4c55d73..91621cf88f 100644
--- a/eng/common/templates/job/execute-sdl.yml
+++ b/eng/common/templates/job/execute-sdl.yml
@@ -10,6 +10,8 @@ jobs:
displayName: Run SDL tool
variables:
- group: DotNet-VSTS-Bot
+ pool:
+ name: Hosted VS2017
steps:
- checkout: self
clean: true
@@ -20,6 +22,16 @@ jobs:
downloadType: specific files
matchingPattern: "**"
downloadPath: $(Build.SourcesDirectory)\artifacts
+ - powershell: eng/common/sdl/extract-artifact-packages.ps1
+ -InputPath $(Build.SourcesDirectory)\artifacts\BlobArtifacts
+ -ExtractPath $(Build.SourcesDirectory)\artifacts\BlobArtifacts
+ displayName: Extract Blob Artifacts
+ continueOnError: ${{ parameters.continueOnError }}
+ - powershell: eng/common/sdl/extract-artifact-packages.ps1
+ -InputPath $(Build.SourcesDirectory)\artifacts\PackageArtifacts
+ -ExtractPath $(Build.SourcesDirectory)\artifacts\PackageArtifacts
+ displayName: Extract Package Artifacts
+ continueOnError: ${{ parameters.continueOnError }}
- task: NuGetToolInstaller@1
displayName: 'Install NuGet.exe'
- task: NuGetCommand@2
@@ -36,7 +48,7 @@ jobs:
continueOnError: ${{ parameters.continueOnError }}
- ${{ if eq(parameters.overrideParameters, '') }}:
- powershell: eng/common/sdl/execute-all-sdl-tools.ps1
- -GuardianPackageName Microsoft.Guardian.Cli.0.3.2
+ -GuardianPackageName Microsoft.Guardian.Cli.0.7.1
-NugetPackageDirectory $(Build.SourcesDirectory)\.packages
-AzureDevOpsAccessToken $(dn-bot-dotnet-build-rw-code-rw)
${{ parameters.additionalParameters }}
diff --git a/eng/common/templates/job/job.yml b/eng/common/templates/job/job.yml
index 1814e0ab61..8db456bb7f 100644
--- a/eng/common/templates/job/job.yml
+++ b/eng/common/templates/job/job.yml
@@ -37,6 +37,9 @@ parameters:
# Optional: Enable publishing to the build asset registry
enablePublishBuildAssets: false
+ # Optional: Prevent gather/push manifest from executing when using publishing pipelines
+ enablePublishUsingPipelines: false
+
# Optional: Include PublishTestResults task
enablePublishTestResults: false
@@ -187,7 +190,7 @@ jobs:
continueOnError: true
condition: always()
- - ${{ if and(eq(parameters.enablePublishBuildAssets, true), ne(variables['_PublishUsingPipelines'], 'true'), eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}:
+ - ${{ if and(eq(parameters.enablePublishBuildAssets, true), ne(parameters.enablePublishUsingPipelines, 'true'), eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}:
- task: CopyFiles@2
displayName: Gather Asset Manifests
inputs:
@@ -195,6 +198,7 @@ jobs:
TargetFolder: '$(Build.StagingDirectory)/AssetManifests'
continueOnError: ${{ parameters.continueOnError }}
condition: and(succeeded(), eq(variables['_DotNetPublishToBlobFeed'], 'true'))
+
- task: PublishBuildArtifacts@1
displayName: Push Asset Manifests
inputs:
diff --git a/eng/common/templates/job/performance.yml b/eng/common/templates/job/performance.yml
new file mode 100644
index 0000000000..ef809253d1
--- /dev/null
+++ b/eng/common/templates/job/performance.yml
@@ -0,0 +1,93 @@
+parameters:
+ steps: [] # optional -- any additional steps that need to happen before pulling down the performance repo and sending the performance benchmarks to helix (ie building your repo)
+ variables: [] # optional -- list of additional variables to send to the template
+ jobName: '' # required -- job name
+ displayName: '' # optional -- display name for the job. Will use jobName if not passed
+ pool: '' # required -- name of the Build pool
+ container: '' # required -- name of the container
+ extraSetupParameters: '' # optional -- extra arguments to pass to the setup script
+ frameworks: ['netcoreapp3.0'] # optional -- list of frameworks to run against
+ continueOnError: 'false' # optional -- determines whether to continue the build if the step errors
+ dependsOn: '' # optional -- dependencies of the job
+ timeoutInMinutes: 320 # optional -- timeout for the job
+ enableTelemetry: false # optional -- enable for telemetry
+
+jobs:
+- template: ../jobs/jobs.yml
+ parameters:
+ dependsOn: ${{ parameters.dependsOn }}
+ enableTelemetry: ${{ parameters.enableTelemetry }}
+ enablePublishBuildArtifacts: true
+ continueOnError: ${{ parameters.continueOnError }}
+
+ jobs:
+ - job: '${{ parameters.jobName }}'
+
+ ${{ if ne(parameters.displayName, '') }}:
+ displayName: '${{ parameters.displayName }}'
+ ${{ if eq(parameters.displayName, '') }}:
+ displayName: '${{ parameters.jobName }}'
+
+ timeoutInMinutes: ${{ parameters.timeoutInMinutes }}
+
+ variables:
+
+ - ${{ each variable in parameters.variables }}:
+ - ${{ if ne(variable.name, '') }}:
+ - name: ${{ variable.name }}
+ value: ${{ variable.value }}
+ - ${{ if ne(variable.group, '') }}:
+ - group: ${{ variable.group }}
+
+ - IsInternal: ''
+ - HelixApiAccessToken: ''
+ - HelixPreCommand: ''
+
+ - ${{ if and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}:
+ - ${{ if eq(variables['Agent.Os'], 'Windows_NT') }}:
+ - HelixPreCommand: 'set "PERFLAB_UPLOAD_TOKEN=$(PerfCommandUploadToken)"'
+ - IsInternal: -Internal
+ - ${{ if ne(variables['Agent.Os'], 'Windows_NT') }}:
+ - HelixPreCommand: 'export PERFLAB_UPLOAD_TOKEN="$(PerfCommandUploadTokenLinux)"'
+ - IsInternal: --internal
+ - group: DotNet-HelixApi-Access
+ - group: dotnet-benchview
+
+ workspace:
+ clean: all
+ pool:
+ ${{ parameters.pool }}
+ container: ${{ parameters.container }}
+ strategy:
+ matrix:
+ ${{ each framework in parameters.frameworks }}:
+ ${{ framework }}:
+ _Framework: ${{ framework }}
+ steps:
+ - checkout: self
+ clean: true
+ # Run all of the steps to setup repo
+ - ${{ each step in parameters.steps }}:
+ - ${{ step }}
+ - powershell: $(Build.SourcesDirectory)\eng\common\performance\performance-setup.ps1 $(IsInternal) -Framework $(_Framework) ${{ parameters.extraSetupParameters }}
+ displayName: Performance Setup (Windows)
+ condition: and(succeeded(), eq(variables['Agent.Os'], 'Windows_NT'))
+ continueOnError: ${{ parameters.continueOnError }}
+ - script: $(Build.SourcesDirectory)/eng/common/performance/performance-setup.sh $(IsInternal) --framework $(_Framework) ${{ parameters.extraSetupParameters }}
+ displayName: Performance Setup (Unix)
+ condition: and(succeeded(), ne(variables['Agent.Os'], 'Windows_NT'))
+ continueOnError: ${{ parameters.continueOnError }}
+ - script: $(Python) $(PerformanceDirectory)/scripts/ci_setup.py $(SetupArguments)
+ displayName: Run ci setup script
+ # Run perf testing in helix
+ - template: /eng/common/templates/steps/perf-send-to-helix.yml
+ parameters:
+ HelixSource: '$(HelixSourcePrefix)/$(Build.Repository.Name)/$(Build.SourceBranch)' # sources must start with pr/, official/, prodcon/, or agent/
+ HelixType: 'test/performance/$(Kind)/$(_Framework)/$(Architecture)'
+ HelixAccessToken: $(HelixApiAccessToken)
+ HelixTargetQueues: $(Queue)
+ HelixPreCommands: $(HelixPreCommand)
+ Creator: $(Creator)
+ WorkItemTimeout: 4:00 # 4 hours
+ WorkItemDirectory: '$(WorkItemDirectory)' # WorkItemDirectory can not be empty, so we send it some docs to keep it happy
+ CorrelationPayloadDirectory: '$(PayloadDirectory)' # it gets checked out to a folder with shorter path than WorkItemDirectory so we can avoid file name too long exceptions
\ No newline at end of file
diff --git a/eng/common/templates/job/publish-build-assets.yml b/eng/common/templates/job/publish-build-assets.yml
index ff7346163f..9e77ef1b54 100644
--- a/eng/common/templates/job/publish-build-assets.yml
+++ b/eng/common/templates/job/publish-build-assets.yml
@@ -66,7 +66,6 @@ jobs:
script: |
Add-Content -Path "$(Build.StagingDirectory)/ReleaseConfigs.txt" -Value $(BARBuildId)
Add-Content -Path "$(Build.StagingDirectory)/ReleaseConfigs.txt" -Value "$(DefaultChannels)"
- Add-Content -Path "$(Build.StagingDirectory)/ReleaseConfigs.txt" -Value $(IsInternalBuild)
Add-Content -Path "$(Build.StagingDirectory)/ReleaseConfigs.txt" -Value $(IsStableBuild)
- task: PublishBuildArtifacts@1
displayName: Publish ReleaseConfigs Artifact
diff --git a/eng/common/templates/post-build/channels/internal-servicing.yml b/eng/common/templates/post-build/channels/internal-servicing.yml
new file mode 100644
index 0000000000..dc065ab308
--- /dev/null
+++ b/eng/common/templates/post-build/channels/internal-servicing.yml
@@ -0,0 +1,147 @@
+parameters:
+ enableSymbolValidation: true
+
+stages:
+- stage: IS_Publish
+ dependsOn: validate
+ variables:
+ - template: ../common-variables.yml
+ displayName: Internal Servicing
+ jobs:
+ - template: ../setup-maestro-vars.yml
+
+ - job:
+ displayName: Symbol Publishing
+ dependsOn: setupMaestroVars
+ condition: contains(dependencies.setupMaestroVars.outputs['setReleaseVars.InitialChannels'], format('[{0}]', variables.InternalServicing_30_Channel_Id))
+ variables:
+ - group: DotNet-Symbol-Server-Pats
+ pool:
+ vmImage: 'windows-2019'
+ steps:
+ - task: DownloadBuildArtifacts@0
+ displayName: Download Artifacts
+ inputs:
+ downloadType: specific files
+ matchingPattern: "*Artifacts*"
+
+ - task: PowerShell@2
+ displayName: Publish
+ inputs:
+ filePath: eng\common\sdk-task.ps1
+ arguments: -task PublishToSymbolServers -restore -msbuildEngine dotnet
+ /p:DotNetSymbolServerTokenMsdl=$(microsoft-symbol-server-pat)
+ /p:DotNetSymbolServerTokenSymWeb=$(symweb-symbol-server-pat)
+ /p:PDBArtifactsDirectory='$(Build.ArtifactStagingDirectory)/PDBArtifacts/'
+ /p:BlobBasePath='$(Build.ArtifactStagingDirectory)/BlobArtifacts/'
+ /p:Configuration=Release
+
+ - job: publish_assets
+ displayName: Publish Assets
+ dependsOn: setupMaestroVars
+ variables:
+ - group: DotNet-Blob-Feed
+ - group: AzureDevOps-Artifact-Feeds-Pats
+ - name: BARBuildId
+ value: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.BARBuildId'] ]
+ - name: IsStableBuild
+ value: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.IsStableBuild'] ]
+ condition: contains(dependencies.setupMaestroVars.outputs['setReleaseVars.InitialChannels'], format('[{0}]', variables.InternalServicing_30_Channel_Id))
+ pool:
+ vmImage: 'windows-2019'
+ steps:
+ - task: DownloadBuildArtifacts@0
+ displayName: Download Package Artifacts
+ inputs:
+ buildType: current
+ artifactName: PackageArtifacts
+
+ - task: DownloadBuildArtifacts@0
+ displayName: Download Blob Artifacts
+ inputs:
+ buildType: current
+ artifactName: BlobArtifacts
+
+ - task: DownloadBuildArtifacts@0
+ displayName: Download Asset Manifests
+ inputs:
+ buildType: current
+ artifactName: AssetManifests
+
+ - task: PowerShell@2
+ displayName: Add Assets Location
+ env:
+ AZURE_DEVOPS_EXT_PAT: $(dn-bot-dnceng-unviersal-packages-rw)
+ inputs:
+ filePath: eng\common\sdk-task.ps1
+ arguments: -task PublishArtifactsInManifest -restore -msbuildEngine dotnet
+ /p:ChannelId=$(InternalServicing_30_Channel_Id)
+ /p:IsStableBuild=$(IsStableBuild)
+ /p:IsInternalBuild=$(IsInternalBuild)
+ /p:RepositoryName=$(Build.Repository.Name)
+ /p:CommitSha=$(Build.SourceVersion)
+ /p:AzureStorageAccountName=$(ProxyBackedFeedsAccountName)
+ /p:AzureStorageAccountKey=$(dotnetfeed-storage-access-key-1)
+ /p:AzureDevOpsFeedsBaseUrl=$(dotnetfeed-internal-private-feed-url)
+ /p:StaticInternalFeed=$(dotnetfeed-internal-nonstable-feed-url)
+ /p:NugetPath=$(Agent.BuildDirectory)\Nuget\NuGet.exe
+ /p:BARBuildId=$(BARBuildId)
+ /p:MaestroApiEndpoint='$(MaestroApiEndPoint)'
+ /p:BuildAssetRegistryToken='$(MaestroApiAccessToken)'
+ /p:ManifestsBasePath='$(Build.ArtifactStagingDirectory)/AssetManifests/'
+ /p:BlobBasePath='$(Build.ArtifactStagingDirectory)\BlobArtifacts'
+ /p:PackageBasePath='$(Build.ArtifactStagingDirectory)\PackageArtifacts'
+ /p:Configuration=Release
+
+ - task: NuGetCommand@2
+ displayName: Publish Packages to AzDO Feed
+ condition: contains(variables['TargetAzDOFeed'], 'pkgs.visualstudio.com')
+ inputs:
+ command: push
+ vstsFeed: $(AzDoFeedName)
+ packagesToPush: $(Build.ArtifactStagingDirectory)\PackageArtifacts\*.nupkg
+ publishVstsFeed: $(AzDoFeedName)
+
+ - task: PowerShell@2
+ displayName: Publish Blobs to AzDO Feed
+ inputs:
+ filePath: $(Build.SourcesDirectory)/eng/common/post-build/publish-blobs-to-azdo.ps1
+ arguments: -FeedName $(AzDoFeedName)
+ -SourceFolderCollection $(Build.ArtifactStagingDirectory)/BlobArtifacts/
+ -PersonalAccessToken $(dn-bot-dnceng-unviersal-packages-rw)
+ enabled: false
+
+ - template: ../trigger-subscription.yml
+ parameters:
+ ChannelId: ${{ variables.InternalServicing_30_Channel_Id }}
+
+- stage: IS_PublishValidation
+ displayName: Publish Validation
+ variables:
+ - template: ../common-variables.yml
+ jobs:
+ - template: ../setup-maestro-vars.yml
+
+ - ${{ if eq(parameters.enableSymbolValidation, 'true') }}:
+ - job:
+ displayName: Symbol Availability
+ dependsOn: setupMaestroVars
+ condition: contains(dependencies.setupMaestroVars.outputs['setReleaseVars.InitialChannels'], format('[{0}]', variables.InternalServicing_30_Channel_Id))
+ pool:
+ vmImage: 'windows-2019'
+ steps:
+ - task: DownloadBuildArtifacts@0
+ displayName: Download Package Artifacts
+ inputs:
+ buildType: current
+ artifactName: PackageArtifacts
+
+ - task: PowerShell@2
+ displayName: Check Symbol Availability
+ inputs:
+ filePath: $(Build.SourcesDirectory)/eng/common/post-build/symbols-validation.ps1
+ arguments: -InputPath $(Build.ArtifactStagingDirectory)/PackageArtifacts/ -ExtractPath $(Agent.BuildDirectory)/Temp/ -DotnetSymbolVersion $(SymbolToolVersion)
+
+ - template: ../promote-build.yml
+ parameters:
+ ChannelId: ${{ variables.InternalServicing_30_Channel_Id }}
diff --git a/eng/common/templates/post-build/channels/netcore-dev-5.yml b/eng/common/templates/post-build/channels/netcore-dev-5.yml
new file mode 100644
index 0000000000..f2b0cfb269
--- /dev/null
+++ b/eng/common/templates/post-build/channels/netcore-dev-5.yml
@@ -0,0 +1,148 @@
+parameters:
+ enableSymbolValidation: true
+
+stages:
+- stage: NetCore_Dev5_Publish
+ dependsOn: validate
+ variables:
+ - template: ../common-variables.yml
+ displayName: .NET Core 5 Dev Channel
+ jobs:
+ - template: ../setup-maestro-vars.yml
+
+ - job:
+ displayName: Symbol Publishing
+ dependsOn: setupMaestroVars
+ condition: contains(dependencies.setupMaestroVars.outputs['setReleaseVars.InitialChannels'], format('[{0}]', variables.NetCore_5_Dev_Channel_Id))
+ variables:
+ - group: DotNet-Symbol-Server-Pats
+ pool:
+ vmImage: 'windows-2019'
+ steps:
+ - task: DownloadBuildArtifacts@0
+ displayName: Download Artifacts
+ inputs:
+ downloadType: specific files
+ matchingPattern: "*Artifacts*"
+
+ - task: PowerShell@2
+ displayName: Publish
+ inputs:
+ filePath: eng\common\sdk-task.ps1
+ arguments: -task PublishToSymbolServers -restore -msbuildEngine dotnet
+ /p:DotNetSymbolServerTokenMsdl=$(microsoft-symbol-server-pat)
+ /p:DotNetSymbolServerTokenSymWeb=$(symweb-symbol-server-pat)
+ /p:PDBArtifactsDirectory='$(Build.ArtifactStagingDirectory)/PDBArtifacts/'
+ /p:BlobBasePath='$(Build.ArtifactStagingDirectory)/BlobArtifacts/'
+ /p:Configuration=Release
+
+ - job:
+ displayName: Publish Assets
+ dependsOn: setupMaestroVars
+ variables:
+ - group: DotNet-Blob-Feed
+ - group: AzureDevOps-Artifact-Feeds-Pats
+ - name: BARBuildId
+ value: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.BARBuildId'] ]
+ - name: IsStableBuild
+ value: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.IsStableBuild'] ]
+ condition: contains(dependencies.setupMaestroVars.outputs['setReleaseVars.InitialChannels'], format('[{0}]', variables.NetCore_5_Dev_Channel_Id))
+ pool:
+ vmImage: 'windows-2019'
+ steps:
+ - task: DownloadBuildArtifacts@0
+ displayName: Download Package Artifacts
+ inputs:
+ buildType: current
+ artifactName: PackageArtifacts
+
+ - task: DownloadBuildArtifacts@0
+ displayName: Download Blob Artifacts
+ inputs:
+ buildType: current
+ artifactName: BlobArtifacts
+
+ - task: DownloadBuildArtifacts@0
+ displayName: Download Asset Manifests
+ inputs:
+ buildType: current
+ artifactName: AssetManifests
+
+ - task: PowerShell@2
+ displayName: Add Assets Location
+ env:
+ AZURE_DEVOPS_EXT_PAT: $(dn-bot-dnceng-unviersal-packages-rw)
+ inputs:
+ filePath: eng\common\sdk-task.ps1
+ arguments: -task PublishArtifactsInManifest -restore -msbuildEngine dotnet
+ /p:ChannelId=$(NetCore_5_Dev_Channel_Id)
+ /p:ArtifactsCategory=$(_DotNetArtifactsCategory)
+ /p:IsStableBuild=$(IsStableBuild)
+ /p:IsInternalBuild=$(IsInternalBuild)
+ /p:RepositoryName=$(Build.Repository.Name)
+ /p:CommitSha=$(Build.SourceVersion)
+ /p:NugetPath=$(Agent.BuildDirectory)\Nuget\NuGet.exe
+ /p:AzdoTargetFeedPAT='$(dn-bot-dnceng-unviersal-packages-rw)'
+ /p:TargetFeedPAT='$(dn-bot-dnceng-unviersal-packages-rw)'
+ /p:AzureStorageTargetFeedPAT='$(dotnetfeed-storage-access-key-1)'
+ /p:BARBuildId=$(BARBuildId)
+ /p:MaestroApiEndpoint='$(MaestroApiEndPoint)'
+ /p:BuildAssetRegistryToken='$(MaestroApiAccessToken)'
+ /p:ManifestsBasePath='$(Build.ArtifactStagingDirectory)/AssetManifests/'
+ /p:BlobBasePath='$(Build.ArtifactStagingDirectory)/BlobArtifacts/'
+ /p:PackageBasePath='$(Build.ArtifactStagingDirectory)/PackageArtifacts/'
+ /p:Configuration=Release
+
+ - task: NuGetCommand@2
+ displayName: Publish Packages to AzDO Feed
+ condition: contains(variables['TargetAzDOFeed'], 'pkgs.visualstudio.com')
+ inputs:
+ command: push
+ vstsFeed: $(AzDoFeedName)
+ packagesToPush: $(Build.ArtifactStagingDirectory)\PackageArtifacts\*.nupkg
+ publishVstsFeed: $(AzDoFeedName)
+
+ - task: PowerShell@2
+ displayName: Publish Blobs to AzDO Feed
+ inputs:
+ filePath: $(Build.SourcesDirectory)/eng/common/post-build/publish-blobs-to-azdo.ps1
+ arguments: -FeedName $(AzDoFeedName)
+ -SourceFolderCollection $(Build.ArtifactStagingDirectory)/BlobArtifacts/
+ -PersonalAccessToken $(dn-bot-dnceng-unviersal-packages-rw)
+ enabled: false
+
+
+- stage: NetCore_Dev5_PublishValidation
+ displayName: Publish Validation
+ variables:
+ - template: ../common-variables.yml
+ jobs:
+ - template: ../setup-maestro-vars.yml
+
+ - ${{ if eq(parameters.enableSymbolValidation, 'true') }}:
+ - job:
+ displayName: Symbol Availability
+ dependsOn: setupMaestroVars
+ condition: contains(dependencies.setupMaestroVars.outputs['setReleaseVars.InitialChannels'], format('[{0}]', variables.NetCore_5_Dev_Channel_Id))
+ pool:
+ vmImage: 'windows-2019'
+ steps:
+ - task: DownloadBuildArtifacts@0
+ displayName: Download Package Artifacts
+ inputs:
+ buildType: current
+ artifactName: PackageArtifacts
+
+ - task: PowerShell@2
+ displayName: Check Symbol Availability
+ inputs:
+ filePath: $(Build.SourcesDirectory)/eng/common/post-build/symbols-validation.ps1
+ arguments: -InputPath $(Build.ArtifactStagingDirectory)/PackageArtifacts/ -ExtractPath $(Agent.BuildDirectory)/Temp/ -DotnetSymbolVersion $(SymbolToolVersion)
+
+ - template: ../darc-gather-drop.yml
+ parameters:
+ ChannelId: ${{ variables.NetCore_5_Dev_Channel_Id }}
+
+ - template: ../promote-build.yml
+ parameters:
+ ChannelId: ${{ variables.NetCore_5_Dev_Channel_Id }}
diff --git a/eng/common/templates/post-build/channels/netcore-tools-latest.yml b/eng/common/templates/post-build/channels/netcore-tools-latest.yml
new file mode 100644
index 0000000000..fd6c09b227
--- /dev/null
+++ b/eng/common/templates/post-build/channels/netcore-tools-latest.yml
@@ -0,0 +1,148 @@
+parameters:
+ enableSymbolValidation: true
+
+stages:
+- stage: NetCore_Tools_Latest_Publish
+ dependsOn: validate
+ variables:
+ - template: ../common-variables.yml
+ displayName: .NET Tools - Latest
+ jobs:
+ - template: ../setup-maestro-vars.yml
+
+ - job:
+ displayName: Symbol Publishing
+ dependsOn: setupMaestroVars
+ condition: contains(dependencies.setupMaestroVars.outputs['setReleaseVars.InitialChannels'], format('[{0}]', variables.NetCore_Tools_Latest_Channel_Id))
+ variables:
+ - group: DotNet-Symbol-Server-Pats
+ pool:
+ vmImage: 'windows-2019'
+ steps:
+ - task: DownloadBuildArtifacts@0
+ displayName: Download Artifacts
+ inputs:
+ downloadType: specific files
+ matchingPattern: "*Artifacts*"
+
+ - task: PowerShell@2
+ displayName: Publish
+ inputs:
+ filePath: eng\common\sdk-task.ps1
+ arguments: -task PublishToSymbolServers -restore -msbuildEngine dotnet
+ /p:DotNetSymbolServerTokenMsdl=$(microsoft-symbol-server-pat)
+ /p:DotNetSymbolServerTokenSymWeb=$(symweb-symbol-server-pat)
+ /p:PDBArtifactsDirectory='$(Build.ArtifactStagingDirectory)/PDBArtifacts/'
+ /p:BlobBasePath='$(Build.ArtifactStagingDirectory)/BlobArtifacts/'
+ /p:Configuration=Release
+
+ - job:
+ displayName: Publish Assets
+ dependsOn: setupMaestroVars
+ variables:
+ - group: DotNet-Blob-Feed
+ - group: AzureDevOps-Artifact-Feeds-Pats
+ - name: BARBuildId
+ value: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.BARBuildId'] ]
+ - name: IsStableBuild
+ value: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.IsStableBuild'] ]
+ condition: contains(dependencies.setupMaestroVars.outputs['setReleaseVars.InitialChannels'], format('[{0}]', variables.NetCore_Tools_Latest_Channel_Id))
+ pool:
+ vmImage: 'windows-2019'
+ steps:
+ - task: DownloadBuildArtifacts@0
+ displayName: Download Package Artifacts
+ inputs:
+ buildType: current
+ artifactName: PackageArtifacts
+
+ - task: DownloadBuildArtifacts@0
+ displayName: Download Blob Artifacts
+ inputs:
+ buildType: current
+ artifactName: BlobArtifacts
+
+ - task: DownloadBuildArtifacts@0
+ displayName: Download Asset Manifests
+ inputs:
+ buildType: current
+ artifactName: AssetManifests
+
+ - task: PowerShell@2
+ displayName: Add Assets Location
+ env:
+ AZURE_DEVOPS_EXT_PAT: $(dn-bot-dnceng-unviersal-packages-rw)
+ inputs:
+ filePath: eng\common\sdk-task.ps1
+ arguments: -task PublishArtifactsInManifest -restore -msbuildEngine dotnet
+ /p:ChannelId=$(NetCore_Tools_Latest_Channel_Id)
+ /p:ArtifactsCategory=$(_DotNetArtifactsCategory)
+ /p:IsStableBuild=$(IsStableBuild)
+ /p:IsInternalBuild=$(IsInternalBuild)
+ /p:RepositoryName=$(Build.Repository.Name)
+ /p:CommitSha=$(Build.SourceVersion)
+ /p:NugetPath=$(Agent.BuildDirectory)\Nuget\NuGet.exe
+ /p:AzdoTargetFeedPAT='$(dn-bot-dnceng-unviersal-packages-rw)'
+ /p:TargetFeedPAT='$(dn-bot-dnceng-unviersal-packages-rw)'
+ /p:AzureStorageTargetFeedPAT='$(dotnetfeed-storage-access-key-1)'
+ /p:BARBuildId=$(BARBuildId)
+ /p:MaestroApiEndpoint='$(MaestroApiEndPoint)'
+ /p:BuildAssetRegistryToken='$(MaestroApiAccessToken)'
+ /p:ManifestsBasePath='$(Build.ArtifactStagingDirectory)/AssetManifests/'
+ /p:BlobBasePath='$(Build.ArtifactStagingDirectory)/BlobArtifacts/'
+ /p:PackageBasePath='$(Build.ArtifactStagingDirectory)/PackageArtifacts/'
+ /p:Configuration=Release
+
+ - task: NuGetCommand@2
+ displayName: Publish Packages to AzDO Feed
+ condition: contains(variables['TargetAzDOFeed'], 'pkgs.visualstudio.com')
+ inputs:
+ command: push
+ vstsFeed: $(AzDoFeedName)
+ packagesToPush: $(Build.ArtifactStagingDirectory)\PackageArtifacts\*.nupkg
+ publishVstsFeed: $(AzDoFeedName)
+
+ - task: PowerShell@2
+ displayName: Publish Blobs to AzDO Feed
+ inputs:
+ filePath: $(Build.SourcesDirectory)/eng/common/post-build/publish-blobs-to-azdo.ps1
+ arguments: -FeedName $(AzDoFeedName)
+ -SourceFolderCollection $(Build.ArtifactStagingDirectory)/BlobArtifacts/
+ -PersonalAccessToken $(dn-bot-dnceng-unviersal-packages-rw)
+ enabled: false
+
+
+- stage: NetCore_Tools_Latest_PublishValidation
+ displayName: Publish Validation
+ variables:
+ - template: ../common-variables.yml
+ jobs:
+ - template: ../setup-maestro-vars.yml
+
+ - ${{ if eq(parameters.enableSymbolValidation, 'true') }}:
+ - job:
+ displayName: Symbol Availability
+ dependsOn: setupMaestroVars
+ condition: contains(dependencies.setupMaestroVars.outputs['setReleaseVars.InitialChannels'], format('[{0}]', variables.NetCore_Tools_Latest_Channel_Id))
+ pool:
+ vmImage: 'windows-2019'
+ steps:
+ - task: DownloadBuildArtifacts@0
+ displayName: Download Package Artifacts
+ inputs:
+ buildType: current
+ artifactName: PackageArtifacts
+
+ - task: PowerShell@2
+ displayName: Check Symbol Availability
+ inputs:
+ filePath: $(Build.SourcesDirectory)/eng/common/post-build/symbols-validation.ps1
+ arguments: -InputPath $(Build.ArtifactStagingDirectory)/PackageArtifacts/ -ExtractPath $(Agent.BuildDirectory)/Temp/ -DotnetSymbolVersion $(SymbolToolVersion)
+
+ - template: ../darc-gather-drop.yml
+ parameters:
+ ChannelId: ${{ variables.NetCore_Tools_Latest_Channel_Id }}
+
+ - template: ../promote-build.yml
+ parameters:
+ ChannelId: ${{ variables.NetCore_Tools_Latest_Channel_Id }}
diff --git a/eng/common/templates/post-build/channels/public-dev-release.yml b/eng/common/templates/post-build/channels/public-dev-release.yml
index c61eaa927d..771dcf4ef8 100644
--- a/eng/common/templates/post-build/channels/public-dev-release.yml
+++ b/eng/common/templates/post-build/channels/public-dev-release.yml
@@ -13,24 +13,17 @@ stages:
- job:
displayName: Symbol Publishing
dependsOn: setupMaestroVars
- condition: contains(dependencies.setupMaestroVars.outputs['setReleaseVars.InitialChannels'], variables.PublicDevRelease_30_Channel_Id)
+ condition: contains(dependencies.setupMaestroVars.outputs['setReleaseVars.InitialChannels'], format('[{0}]', variables.PublicDevRelease_30_Channel_Id))
variables:
- group: DotNet-Symbol-Server-Pats
pool:
vmImage: 'windows-2019'
steps:
- task: DownloadBuildArtifacts@0
- displayName: Download PDB Artifacts
+ displayName: Download Artifacts
inputs:
- buildType: current
- artifactName: PDBArtifacts
- continueOnError: true
-
- - task: DownloadBuildArtifacts@0
- displayName: Download Blob Artifacts
- inputs:
- buildType: current
- artifactName: BlobArtifacts
+ downloadType: specific files
+ matchingPattern: "*Artifacts*"
- task: PowerShell@2
displayName: Publish
@@ -44,14 +37,16 @@ stages:
/p:Configuration=Release
- job:
- displayName: Publish to Static Feed
+ displayName: Publish Assets
dependsOn: setupMaestroVars
variables:
- group: DotNet-Blob-Feed
- - group: Publish-Build-Assets
+ - group: AzureDevOps-Artifact-Feeds-Pats
- name: BARBuildId
value: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.BARBuildId'] ]
- condition: contains(dependencies.setupMaestroVars.outputs['setReleaseVars.InitialChannels'], variables.PublicDevRelease_30_Channel_Id)
+ - name: IsStableBuild
+ value: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.IsStableBuild'] ]
+ condition: contains(dependencies.setupMaestroVars.outputs['setReleaseVars.InitialChannels'], format('[{0}]', variables.PublicDevRelease_30_Channel_Id))
pool:
vmImage: 'windows-2019'
steps:
@@ -74,22 +69,48 @@ stages:
artifactName: AssetManifests
- task: PowerShell@2
- displayName: Publish
+ displayName: Add Assets Location
+ env:
+ AZURE_DEVOPS_EXT_PAT: $(dn-bot-dnceng-unviersal-packages-rw)
inputs:
filePath: eng\common\sdk-task.ps1
- arguments: -task PublishToPackageFeed -restore -msbuildEngine dotnet
- /p:AccountKeyToStaticFeed='$(dotnetfeed-storage-access-key-1)'
+ arguments: -task PublishArtifactsInManifest -restore -msbuildEngine dotnet
+ /p:ChannelId=$(PublicDevRelease_30_Channel_Id)
+ /p:ArtifactsCategory=$(_DotNetArtifactsCategory)
+ /p:IsStableBuild=$(IsStableBuild)
+ /p:IsInternalBuild=$(IsInternalBuild)
+ /p:RepositoryName=$(Build.Repository.Name)
+ /p:CommitSha=$(Build.SourceVersion)
+ /p:NugetPath=$(Agent.BuildDirectory)\Nuget\NuGet.exe
+ /p:AzdoTargetFeedPAT='$(dn-bot-dnceng-unviersal-packages-rw)'
+ /p:TargetFeedPAT='$(dn-bot-dnceng-unviersal-packages-rw)'
+ /p:AzureStorageTargetFeedPAT='$(dotnetfeed-storage-access-key-1)'
/p:BARBuildId=$(BARBuildId)
- /p:MaestroApiEndpoint='https://maestro-prod.westus2.cloudapp.azure.com'
- /p:BuildAssetRegistryToken='$(MaestroAccessToken)'
+ /p:MaestroApiEndpoint='$(MaestroApiEndPoint)'
+ /p:BuildAssetRegistryToken='$(MaestroApiAccessToken)'
/p:ManifestsBasePath='$(Build.ArtifactStagingDirectory)/AssetManifests/'
/p:BlobBasePath='$(Build.ArtifactStagingDirectory)/BlobArtifacts/'
/p:PackageBasePath='$(Build.ArtifactStagingDirectory)/PackageArtifacts/'
- /p:ArtifactsCategory='$(_DotNetArtifactsCategory)'
- /p:OverrideAssetsWithSameName=true
- /p:PassIfExistingItemIdentical=true
/p:Configuration=Release
+ - task: NuGetCommand@2
+ displayName: Publish Packages to AzDO Feed
+ condition: contains(variables['TargetAzDOFeed'], 'pkgs.visualstudio.com')
+ inputs:
+ command: push
+ vstsFeed: $(AzDoFeedName)
+ packagesToPush: $(Build.ArtifactStagingDirectory)\PackageArtifacts\*.nupkg
+ publishVstsFeed: $(AzDoFeedName)
+
+ - task: PowerShell@2
+ displayName: Publish Blobs to AzDO Feed
+ inputs:
+ filePath: $(Build.SourcesDirectory)/eng/common/post-build/publish-blobs-to-azdo.ps1
+ arguments: -FeedName $(AzDoFeedName)
+ -SourceFolderCollection $(Build.ArtifactStagingDirectory)/BlobArtifacts/
+ -PersonalAccessToken $(dn-bot-dnceng-unviersal-packages-rw)
+ enabled: false
+
- stage: PublishValidation
displayName: Publish Validation
@@ -102,7 +123,7 @@ stages:
- job:
displayName: Symbol Availability
dependsOn: setupMaestroVars
- condition: contains(dependencies.setupMaestroVars.outputs['setReleaseVars.InitialChannels'], variables.PublicDevRelease_30_Channel_Id)
+ condition: contains(dependencies.setupMaestroVars.outputs['setReleaseVars.InitialChannels'], format('[{0}]', variables.PublicDevRelease_30_Channel_Id))
pool:
vmImage: 'windows-2019'
steps:
@@ -118,28 +139,10 @@ stages:
filePath: $(Build.SourcesDirectory)/eng/common/post-build/symbols-validation.ps1
arguments: -InputPath $(Build.ArtifactStagingDirectory)/PackageArtifacts/ -ExtractPath $(Agent.BuildDirectory)/Temp/ -DotnetSymbolVersion $(SymbolToolVersion)
- - job:
- displayName: Gather Drop
- dependsOn: setupMaestroVars
- variables:
- BARBuildId: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.BARBuildId'] ]
- condition: contains(dependencies.setupMaestroVars.outputs['setReleaseVars.InitialChannels'], variables.PublicDevRelease_30_Channel_Id)
- pool:
- vmImage: 'windows-2019'
- steps:
- - task: PowerShell@2
- displayName: Setup Darc CLI
- inputs:
- targetType: filePath
- filePath: '$(Build.SourcesDirectory)/eng/common/darc-init.ps1'
-
- - task: PowerShell@2
- displayName: Run Darc gather-drop
- inputs:
- targetType: inline
- script: |
- darc gather-drop --non-shipping --continue-on-error --id $(BARBuildId) --output-dir $(Agent.BuildDirectory)/Temp/Drop/ --bar-uri https://maestro-prod.westus2.cloudapp.azure.com/ --password $(MaestroAccessToken) --latest-location
-
- - template: ../promote-build.yml
+ - template: ../darc-gather-drop.yml
parameters:
ChannelId: ${{ variables.PublicDevRelease_30_Channel_Id }}
+
+ - template: ../promote-build.yml
+ parameters:
+ ChannelId: ${{ variables.PublicDevRelease_30_Channel_Id }}
diff --git a/eng/common/templates/post-build/channels/public-release.yml b/eng/common/templates/post-build/channels/public-release.yml
new file mode 100644
index 0000000000..00108bd3f8
--- /dev/null
+++ b/eng/common/templates/post-build/channels/public-release.yml
@@ -0,0 +1,147 @@
+parameters:
+ enableSymbolValidation: true
+
+stages:
+- stage: PubRel_Publish
+ dependsOn: validate
+ variables:
+ - template: ../common-variables.yml
+ displayName: Public Release
+ jobs:
+ - template: ../setup-maestro-vars.yml
+
+ - job:
+ displayName: Symbol Publishing
+ dependsOn: setupMaestroVars
+ condition: contains(dependencies.setupMaestroVars.outputs['setReleaseVars.InitialChannels'], format('[{0}]', variables.PublicRelease_30_Channel_Id))
+ variables:
+ - group: DotNet-Symbol-Server-Pats
+ pool:
+ vmImage: 'windows-2019'
+ steps:
+ - task: DownloadBuildArtifacts@0
+ displayName: Download Artifacts
+ inputs:
+ downloadType: specific files
+ matchingPattern: "*Artifacts*"
+
+ - task: PowerShell@2
+ displayName: Publish
+ inputs:
+ filePath: eng\common\sdk-task.ps1
+ arguments: -task PublishToSymbolServers -restore -msbuildEngine dotnet
+ /p:DotNetSymbolServerTokenMsdl=$(microsoft-symbol-server-pat)
+ /p:DotNetSymbolServerTokenSymWeb=$(symweb-symbol-server-pat)
+ /p:PDBArtifactsDirectory='$(Build.ArtifactStagingDirectory)/PDBArtifacts/'
+ /p:BlobBasePath='$(Build.ArtifactStagingDirectory)/BlobArtifacts/'
+ /p:Configuration=Release
+
+ - job: publish_assets
+ displayName: Publish Assets
+ dependsOn: setupMaestroVars
+ variables:
+ - group: DotNet-Blob-Feed
+ - group: AzureDevOps-Artifact-Feeds-Pats
+ - name: BARBuildId
+ value: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.BARBuildId'] ]
+ - name: IsStableBuild
+ value: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.IsStableBuild'] ]
+ condition: contains(dependencies.setupMaestroVars.outputs['setReleaseVars.InitialChannels'], format('[{0}]', variables.PublicRelease_30_Channel_Id))
+ pool:
+ vmImage: 'windows-2019'
+ steps:
+ - task: DownloadBuildArtifacts@0
+ displayName: Download Package Artifacts
+ inputs:
+ buildType: current
+ artifactName: PackageArtifacts
+
+ - task: DownloadBuildArtifacts@0
+ displayName: Download Blob Artifacts
+ inputs:
+ buildType: current
+ artifactName: BlobArtifacts
+
+ - task: DownloadBuildArtifacts@0
+ displayName: Download Asset Manifests
+ inputs:
+ buildType: current
+ artifactName: AssetManifests
+
+ - task: PowerShell@2
+ displayName: Publish
+ env:
+ AZURE_DEVOPS_EXT_PAT: $(dn-bot-dnceng-unviersal-packages-rw)
+ inputs:
+ filePath: eng\common\sdk-task.ps1
+ arguments: -task PublishArtifactsInManifest -restore -msbuildEngine dotnet
+ /p:ChannelId=$(PublicRelease_30_Channel_Id)
+ /p:IsStableBuild=$(IsStableBuild)
+ /p:IsInternalBuild=$(IsInternalBuild)
+ /p:RepositoryName=$(Build.Repository.Name)
+ /p:CommitSha=$(Build.SourceVersion)
+ /p:AzureStorageAccountName=$(ProxyBackedFeedsAccountName)
+ /p:AzureStorageAccountKey=$(dotnetfeed-storage-access-key-1)
+ /p:AzureDevOpsFeedsBaseUrl=$(dotnetfeed-internal-private-feed-url)
+ /p:StaticInternalFeed=$(dotnetfeed-internal-nonstable-feed-url)
+ /p:NugetPath=$(Agent.BuildDirectory)\Nuget\NuGet.exe
+ /p:BARBuildId=$(BARBuildId)
+ /p:MaestroApiEndpoint='$(MaestroApiEndPoint)'
+ /p:BuildAssetRegistryToken='$(MaestroApiAccessToken)'
+ /p:ManifestsBasePath='$(Build.ArtifactStagingDirectory)/AssetManifests/'
+ /p:BlobBasePath='$(Build.ArtifactStagingDirectory)\BlobArtifacts'
+ /p:PackageBasePath='$(Build.ArtifactStagingDirectory)\PackageArtifacts'
+ /p:Configuration=Release
+
+ - task: NuGetCommand@2
+ displayName: Publish Packages to AzDO Feed
+ condition: contains(variables['TargetAzDOFeed'], 'pkgs.visualstudio.com')
+ inputs:
+ command: push
+ vstsFeed: $(AzDoFeedName)
+ packagesToPush: $(Build.ArtifactStagingDirectory)\PackageArtifacts\*.nupkg
+ publishVstsFeed: $(AzDoFeedName)
+
+ - task: PowerShell@2
+ displayName: Publish Blobs to AzDO Feed
+ inputs:
+ filePath: $(Build.SourcesDirectory)/eng/common/post-build/publish-blobs-to-azdo.ps1
+ arguments: -FeedName $(AzDoFeedName)
+ -SourceFolderCollection $(Build.ArtifactStagingDirectory)/BlobArtifacts/
+ -PersonalAccessToken $(dn-bot-dnceng-unviersal-packages-rw)
+ enabled: false
+
+ - template: ../trigger-subscription.yml
+ parameters:
+ ChannelId: ${{ variables.PublicRelease_30_Channel_Id }}
+
+- stage: PubRel_PublishValidation
+ displayName: Publish Validation
+ variables:
+ - template: ../common-variables.yml
+ jobs:
+ - template: ../setup-maestro-vars.yml
+
+ - ${{ if eq(parameters.enableSymbolValidation, 'true') }}:
+ - job:
+ displayName: Symbol Availability
+ dependsOn: setupMaestroVars
+ condition: contains(dependencies.setupMaestroVars.outputs['setReleaseVars.InitialChannels'], format('[{0}]', variables.PublicRelease_30_Channel_Id))
+ pool:
+ vmImage: 'windows-2019'
+ steps:
+ - task: DownloadBuildArtifacts@0
+ displayName: Download Package Artifacts
+ inputs:
+ buildType: current
+ artifactName: PackageArtifacts
+
+ - task: PowerShell@2
+ displayName: Check Symbol Availability
+ inputs:
+ filePath: $(Build.SourcesDirectory)/eng/common/post-build/symbols-validation.ps1
+ arguments: -InputPath $(Build.ArtifactStagingDirectory)/PackageArtifacts/ -ExtractPath $(Agent.BuildDirectory)/Temp/ -DotnetSymbolVersion $(SymbolToolVersion)
+
+ - template: ../promote-build.yml
+ parameters:
+ ChannelId: ${{ variables.PublicRelease_30_Channel_Id }}
diff --git a/eng/common/templates/post-build/channels/public-validation-release.yml b/eng/common/templates/post-build/channels/public-validation-release.yml
index 23725c6d62..f64184da9f 100644
--- a/eng/common/templates/post-build/channels/public-validation-release.yml
+++ b/eng/common/templates/post-build/channels/public-validation-release.yml
@@ -8,14 +8,16 @@ stages:
- template: ../setup-maestro-vars.yml
- job:
- displayName: Publish to Static Feed
+ displayName: Publish Assets
dependsOn: setupMaestroVars
- condition: contains(dependencies.setupMaestroVars.outputs['setReleaseVars.InitialChannels'], variables.PublicValidationRelease_30_Channel_Id)
variables:
- group: DotNet-Blob-Feed
- - group: Publish-Build-Assets
+ - group: AzureDevOps-Artifact-Feeds-Pats
- name: BARBuildId
value: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.BARBuildId'] ]
+ - name: IsStableBuild
+ value: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.IsStableBuild'] ]
+ condition: contains(dependencies.setupMaestroVars.outputs['setReleaseVars.InitialChannels'], format('[{0}]', variables.PublicValidationRelease_30_Channel_Id))
pool:
vmImage: 'windows-2019'
steps:
@@ -38,22 +40,48 @@ stages:
artifactName: AssetManifests
- task: PowerShell@2
- displayName: Publish
+ displayName: Add Assets Location
+ env:
+ AZURE_DEVOPS_EXT_PAT: $(dn-bot-dnceng-unviersal-packages-rw)
inputs:
filePath: eng\common\sdk-task.ps1
- arguments: -task PublishToPackageFeed -restore -msbuildEngine dotnet
- /p:AccountKeyToStaticFeed='$(dotnetfeed-storage-access-key-1)'
+ arguments: -task PublishArtifactsInManifest -restore -msbuildEngine dotnet
+ /p:ChannelId=$(PublicValidationRelease_30_Channel_Id)
+ /p:ArtifactsCategory=$(_DotNetValidationArtifactsCategory)
+ /p:IsStableBuild=$(IsStableBuild)
+ /p:IsInternalBuild=$(IsInternalBuild)
+ /p:RepositoryName=$(Build.Repository.Name)
+ /p:CommitSha=$(Build.SourceVersion)
+ /p:NugetPath=$(Agent.BuildDirectory)\Nuget\NuGet.exe
+ /p:AzdoTargetFeedPAT='$(dn-bot-dnceng-unviersal-packages-rw)'
+ /p:TargetFeedPAT='$(dn-bot-dnceng-unviersal-packages-rw)'
+ /p:AzureStorageTargetFeedPAT='$(dotnetfeed-storage-access-key-1)'
/p:BARBuildId=$(BARBuildId)
- /p:MaestroApiEndpoint='https://maestro-prod.westus2.cloudapp.azure.com'
- /p:BuildAssetRegistryToken='$(MaestroAccessToken)'
+ /p:MaestroApiEndpoint='$(MaestroApiEndPoint)'
+ /p:BuildAssetRegistryToken='$(MaestroApiAccessToken)'
/p:ManifestsBasePath='$(Build.ArtifactStagingDirectory)/AssetManifests/'
- /p:BlobBasePath='$(Build.ArtifactStagingDirectory)/BlobArtifacts/'
- /p:PackageBasePath='$(Build.ArtifactStagingDirectory)/PackageArtifacts/'
- /p:ArtifactsCategory='$(_DotNetArtifactsCategory)'
- /p:OverrideAssetsWithSameName=true
- /p:PassIfExistingItemIdentical=true
+ /p:BlobBasePath='$(Build.ArtifactStagingDirectory)\BlobArtifacts'
+ /p:PackageBasePath='$(Build.ArtifactStagingDirectory)\PackageArtifacts'
/p:Configuration=Release
+ - task: NuGetCommand@2
+ displayName: Publish Packages to AzDO Feed
+ condition: contains(variables['TargetAzDOFeed'], 'pkgs.visualstudio.com')
+ inputs:
+ command: push
+ vstsFeed: $(AzDoFeedName)
+ packagesToPush: $(Build.ArtifactStagingDirectory)\PackageArtifacts\*.nupkg
+ publishVstsFeed: $(AzDoFeedName)
+
+ - task: PowerShell@2
+ displayName: Publish Blobs to AzDO Feed
+ inputs:
+ filePath: $(Build.SourcesDirectory)/eng/common/post-build/publish-blobs-to-azdo.ps1
+ arguments: -FeedName $(AzDoFeedName)
+ -SourceFolderCollection $(Build.ArtifactStagingDirectory)/BlobArtifacts/
+ -PersonalAccessToken $(dn-bot-dnceng-unviersal-packages-rw)
+ enabled: false
+
- stage: PVR_PublishValidation
displayName: Publish Validation
@@ -62,30 +90,10 @@ stages:
jobs:
- template: ../setup-maestro-vars.yml
- - job:
- displayName: Gather Drop
- dependsOn: setupMaestroVars
- condition: contains(dependencies.setupMaestroVars.outputs['setReleaseVars.InitialChannels'], variables.PublicValidationRelease_30_Channel_Id)
- variables:
- - name: BARBuildId
- value: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.BARBuildId'] ]
- - group: Publish-Build-Assets
- pool:
- vmImage: 'windows-2019'
- steps:
- - task: PowerShell@2
- displayName: Setup Darc CLI
- inputs:
- targetType: filePath
- filePath: '$(Build.SourcesDirectory)/eng/common/darc-init.ps1'
-
- - task: PowerShell@2
- displayName: Run Darc gather-drop
- inputs:
- targetType: inline
- script: |
- darc gather-drop --non-shipping --continue-on-error --id $(BARBuildId) --output-dir $(Agent.BuildDirectory)/Temp/Drop/ --bar-uri https://maestro-prod.westus2.cloudapp.azure.com --password $(MaestroAccessToken) --latest-location
-
- - template: ../promote-build.yml
+ - template: ../darc-gather-drop.yml
parameters:
ChannelId: ${{ variables.PublicValidationRelease_30_Channel_Id }}
+
+ - template: ../promote-build.yml
+ parameters:
+ ChannelId: ${{ variables.PublicValidationRelease_30_Channel_Id }}
diff --git a/eng/common/templates/post-build/common-variables.yml b/eng/common/templates/post-build/common-variables.yml
index 97b48d97fe..52a74487fd 100644
--- a/eng/common/templates/post-build/common-variables.yml
+++ b/eng/common/templates/post-build/common-variables.yml
@@ -1,9 +1,47 @@
variables:
+ - group: Publish-Build-Assets
+
# .NET Core 3 Dev
- PublicDevRelease_30_Channel_Id: 3
+ - name: PublicDevRelease_30_Channel_Id
+ value: 3
+
+ # .NET Core 5 Dev
+ - name: NetCore_5_Dev_Channel_Id
+ value: 131
# .NET Tools - Validation
- PublicValidationRelease_30_Channel_Id: 9
+ - name: PublicValidationRelease_30_Channel_Id
+ value: 9
+
+ # .NET Tools - Latest
+ - name: NetCore_Tools_Latest_Channel_Id
+ value: 2
+
+ # .NET Core 3.0 Internal Servicing
+ - name: InternalServicing_30_Channel_Id
+ value: 184
+
+ # .NET Core 3.0 Release
+ - name: PublicRelease_30_Channel_Id
+ value: 19
+
+ # Whether the build is internal or not
+ - name: IsInternalBuild
+ value: ${{ and(ne(variables['System.TeamProject'], 'public'), contains(variables['Build.SourceBranch'], 'internal')) }}
+
+ # Storage account name for proxy-backed feeds
+ - name: ProxyBackedFeedsAccountName
+ value: dotnetfeed
+
+ # Default Maestro++ API Endpoint and API Version
+ - name: MaestroApiEndPoint
+ value: "https://maestro-prod.westus2.cloudapp.azure.com"
+ - name: MaestroApiAccessToken
+ value: $(MaestroAccessToken)
+ - name: MaestroApiVersion
+ value: "2019-01-16"
- SourceLinkCLIVersion: 3.0.0
- SymbolToolVersion: 1.0.1
+ - name: SourceLinkCLIVersion
+ value: 3.0.0
+ - name: SymbolToolVersion
+ value: 1.0.1
diff --git a/eng/common/templates/post-build/darc-gather-drop.yml b/eng/common/templates/post-build/darc-gather-drop.yml
new file mode 100644
index 0000000000..3268ccaa55
--- /dev/null
+++ b/eng/common/templates/post-build/darc-gather-drop.yml
@@ -0,0 +1,23 @@
+parameters:
+ ChannelId: 0
+
+jobs:
+- job: gatherDrop
+ displayName: Gather Drop
+ dependsOn: setupMaestroVars
+ condition: contains(dependencies.setupMaestroVars.outputs['setReleaseVars.InitialChannels'], format('[{0}]', ${{ parameters.ChannelId }}))
+ variables:
+ - name: BARBuildId
+ value: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.BARBuildId'] ]
+ pool:
+ vmImage: 'windows-2019'
+ steps:
+ - task: PowerShell@2
+ displayName: Darc gather-drop
+ inputs:
+ filePath: $(Build.SourcesDirectory)/eng/common/post-build/darc-gather-drop.ps1
+ arguments: -BarBuildId $(BARBuildId)
+ -DropLocation $(Agent.BuildDirectory)/Temp/Drop/
+ -MaestroApiAccessToken $(MaestroApiAccessToken)
+ -MaestroApiEndPoint $(MaestroApiEndPoint)
+ -MaestroApiVersion $(MaestroApiVersion)
diff --git a/eng/common/templates/post-build/post-build.yml b/eng/common/templates/post-build/post-build.yml
index 2c411dd009..aba0b0fcaf 100644
--- a/eng/common/templates/post-build/post-build.yml
+++ b/eng/common/templates/post-build/post-build.yml
@@ -2,15 +2,38 @@ parameters:
enableSourceLinkValidation: true
enableSigningValidation: true
enableSymbolValidation: true
+ enableNugetValidation: true
SDLValidationParameters:
enable: false
params: ''
+ # Which stages should finish execution before post-build stages start
+ dependsOn: [build]
+
stages:
- stage: validate
- dependsOn: build
+ dependsOn: ${{ parameters.dependsOn }}
displayName: Validate
jobs:
+ - ${{ if eq(parameters.enableNugetValidation, 'true') }}:
+ - job:
+ displayName: NuGet Validation
+ pool:
+ vmImage: 'windows-2019'
+ steps:
+ - task: DownloadBuildArtifacts@0
+ displayName: Download Package Artifacts
+ inputs:
+ buildType: current
+ artifactName: PackageArtifacts
+
+ - task: PowerShell@2
+ displayName: Validate
+ inputs:
+ filePath: $(Build.SourcesDirectory)/eng/common/post-build/nuget-validation.ps1
+ arguments: -PackagesPath $(Build.ArtifactStagingDirectory)/PackageArtifacts/
+ -ToolDestinationPath $(Agent.BuildDirectory)/Extract/
+
- ${{ if eq(parameters.enableSigningValidation, 'true') }}:
- job:
displayName: Signing Validation
@@ -29,6 +52,7 @@ stages:
filePath: eng\common\sdk-task.ps1
arguments: -task SigningValidation -restore -msbuildEngine dotnet
/p:PackageBasePath='$(Build.ArtifactStagingDirectory)/PackageArtifacts'
+ /p:SignCheckExclusionsFile='$(Build.SourcesDirectory)/eng/SignCheckExclusionsFile.txt'
/p:Configuration=Release
- ${{ if eq(parameters.enableSourceLinkValidation, 'true') }}:
@@ -60,8 +84,20 @@ stages:
parameters:
additionalParameters: ${{ parameters.SDLValidationParameters.params }}
+- template: \eng\common\templates\post-build\channels\netcore-dev-5.yml
+ parameters:
+ enableSymbolValidation: ${{ parameters.enableSymbolValidation }}
+
- template: \eng\common\templates\post-build\channels\public-dev-release.yml
parameters:
enableSymbolValidation: ${{ parameters.enableSymbolValidation }}
+- template: \eng\common\templates\post-build\channels\netcore-tools-latest.yml
+ parameters:
+ enableSymbolValidation: ${{ parameters.enableSymbolValidation }}
+
- template: \eng\common\templates\post-build\channels\public-validation-release.yml
+
+- template: \eng\common\templates\post-build\channels\public-release.yml
+
+- template: \eng\common\templates\post-build\channels\internal-servicing.yml
diff --git a/eng/common/templates/post-build/promote-build.yml b/eng/common/templates/post-build/promote-build.yml
index d00317003b..6b479c3b82 100644
--- a/eng/common/templates/post-build/promote-build.yml
+++ b/eng/common/templates/post-build/promote-build.yml
@@ -5,24 +5,21 @@ jobs:
- job:
displayName: Promote Build
dependsOn: setupMaestroVars
- condition: contains(dependencies.setupMaestroVars.outputs['setReleaseVars.InitialChannels'], ${{ parameters.ChannelId }})
+ condition: contains(dependencies.setupMaestroVars.outputs['setReleaseVars.InitialChannels'], format('[{0}]', ${{ parameters.ChannelId }}))
variables:
- name: BARBuildId
value: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.BARBuildId'] ]
- name: ChannelId
value: ${{ parameters.ChannelId }}
- - group: Publish-Build-Assets
pool:
vmImage: 'windows-2019'
steps:
- task: PowerShell@2
displayName: Add Build to Channel
inputs:
- targetType: inline
- script: |
- $headers = @{
- "Accept" = "application/json"
- "Authorization" = "Bearer $(MaestroAccessToken)"
- }
- Invoke-RestMethod -Method Post -Headers $headers -Uri https://maestro-prod.westus2.cloudapp.azure.com/api/channels/$(ChannelId)/builds/$(BARBuildId)?api-version=2019-01-16
- enabled: false
+ filePath: $(Build.SourcesDirectory)/eng/common/post-build/promote-build.ps1
+ arguments: -BuildId $(BARBuildId)
+ -ChannelId $(ChannelId)
+ -MaestroApiAccessToken $(MaestroApiAccessToken)
+ -MaestroApiEndPoint $(MaestroApiEndPoint)
+ -MaestroApiVersion $(MaestroApiVersion)
diff --git a/eng/common/templates/post-build/setup-maestro-vars.yml b/eng/common/templates/post-build/setup-maestro-vars.yml
index 0eddd6cd3b..56242b068e 100644
--- a/eng/common/templates/post-build/setup-maestro-vars.yml
+++ b/eng/common/templates/post-build/setup-maestro-vars.yml
@@ -14,24 +14,5 @@ jobs:
name: setReleaseVars
displayName: Set Release Configs Vars
inputs:
- targetType: inline
- script: |
- # This is needed to make Write-PipelineSetVariable works in this context
- $ci = $true
-
- . "$(Build.SourcesDirectory)/eng/common/tools.ps1"
-
- $Content = Get-Content "$(Build.StagingDirectory)/ReleaseConfigs/ReleaseConfigs.txt"
-
- $BarId = $Content | Select -Index 0
-
- $Channels = ""
- $Content | Select -Index 1 | ForEach-Object { $Channels += "$_ ," }
-
- $IsInternalBuild = $Content | Select -Index 2
- $IsStableBuild = $Content | Select -Index 3
-
- Write-PipelineSetVariable -Name 'BARBuildId' -Value $BarId
- Write-PipelineSetVariable -Name 'InitialChannels' -Value "$Channels"
- Write-PipelineSetVariable -Name 'IsInternalBuild' -Value $IsInternalBuild
- Write-PipelineSetVariable -Name 'IsStableBuild' -Value $IsStableBuild
+ filePath: $(Build.SourcesDirectory)/eng/common/post-build/setup-maestro-vars.ps1
+ arguments: -ReleaseConfigsPath '$(Build.StagingDirectory)/ReleaseConfigs/ReleaseConfigs.txt'
diff --git a/eng/common/templates/post-build/trigger-subscription.yml b/eng/common/templates/post-build/trigger-subscription.yml
new file mode 100644
index 0000000000..da669030da
--- /dev/null
+++ b/eng/common/templates/post-build/trigger-subscription.yml
@@ -0,0 +1,13 @@
+parameters:
+ ChannelId: 0
+
+steps:
+- task: PowerShell@2
+ displayName: Triggering subscriptions
+ inputs:
+ filePath: $(Build.SourcesDirectory)/eng/common/post-build/trigger-subscriptions.ps1
+ arguments: -SourceRepo $(Build.Repository.Uri)
+ -ChannelId ${{ parameters.ChannelId }}
+ -MaestroApiAccessToken $(MaestroAccessToken)
+ -MaestroApiEndPoint $(MaestroApiEndPoint)
+ -MaestroApiVersion $(MaestroApiVersion)
diff --git a/eng/common/templates/steps/helix-publish.yml b/eng/common/templates/steps/helix-publish.yml
deleted file mode 100644
index 470ab65da0..0000000000
--- a/eng/common/templates/steps/helix-publish.yml
+++ /dev/null
@@ -1,51 +0,0 @@
-parameters:
- HelixSource: 'pr/dotnet-github-anon-kaonashi-bot'
- HelixType: ̓'tests/default'
- HelixBuild: $(Build.BuildNumber)
- HelixTargetQueues: ''
- HelixAccessToken: ''
- HelixPreCommands: ''
- HelixPostCommands: ''
- WorkItemDirectory: ''
- WorkItemCommand: ''
- CorrelationPayloadDirectory: ''
- XUnitProjects: ''
- XUnitTargetFramework: ''
- XUnitRunnerVersion: ''
- IncludeDotNetCli: false
- DotNetCliPackageType: ''
- DotNetCliVersion: ''
- EnableXUnitReporter: false
- WaitForWorkItemCompletion: true
- condition: succeeded()
- continueOnError: false
-
-steps:
- - task: DotNetCoreCLI@2
- inputs:
- command: custom
- projects: eng/common/helixpublish.proj
- custom: msbuild
- arguments: '/bl:$(Build.SourcesDirectory)/artifacts/log/$(_BuildConfig)/SendToHelix.binlog'
- displayName: Send job to Helix
- env:
- HelixSource: ${{ parameters.HelixSource }}
- HelixType: ${{ parameters.HelixType }}
- HelixBuild: ${{ parameters.HelixBuild }}
- HelixTargetQueues: ${{ parameters.HelixTargetQueues }}
- HelixAccessToken: ${{ parameters.HelixAccessToken }}
- HelixPreCommands: ${{ parameters.HelixPreCommands }}
- HelixPostCommands: ${{ parameters.HelixPostCommands }}
- WorkItemDirectory: ${{ parameters.WorkItemDirectory }}
- WorkItemCommand: ${{ parameters.WorkItemCommand }}
- CorrelationPayloadDirectory: ${{ parameters.CorrelationPayloadDirectory }}
- XUnitProjects: ${{ parameters.XUnitProjects }}
- XUnitRuntimeTargetFramework: ${{ parameters.XUnitTargetFramework }}
- XUnitRunnerVersion: ${{ parameters.XUnitRunnerVersion }}
- IncludeDotNetCli: ${{ parameters.IncludeDotNetCli }}
- DotNetCliPackageType: ${{ parameters.DotNetCliPackageType }}
- DotNetCliVersion: ${{ parameters.DotNetCliVersion }}
- EnableXUnitReporter: ${{ parameters.EnableXUnitReporter }}
- WaitForWorkItemCompletion: ${{ parameters.WaitForWorkItemCompletion }}
- condition: ${{ parameters.condition }}
- continueOnError: ${{ parameters.continueOnError }}
diff --git a/eng/common/templates/steps/perf-send-to-helix.yml b/eng/common/templates/steps/perf-send-to-helix.yml
new file mode 100644
index 0000000000..b3ea9acf1f
--- /dev/null
+++ b/eng/common/templates/steps/perf-send-to-helix.yml
@@ -0,0 +1,66 @@
+# Please remember to update the documentation if you make changes to these parameters!
+parameters:
+ HelixSource: 'pr/default' # required -- sources must start with pr/, official/, prodcon/, or agent/
+ HelixType: 'tests/default/' # required -- Helix telemetry which identifies what type of data this is; should include "test" for clarity and must end in '/'
+ 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
+ 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
+ CorrelationPayloadDirectory: '' # optional -- a directory to zip up and send to Helix as a correlation payload
+ IncludeDotNetCli: false # optional -- true will download a version of the .NET CLI onto the Helix machine as a correlation payload; requires DotNetCliPackageType and DotNetCliVersion
+ DotNetCliPackageType: '' # optional -- either 'sdk' or 'runtime'; determines whether the sdk or runtime will be sent to Helix; see https://raw.githubusercontent.com/dotnet/core/master/release-notes/releases.json
+ DotNetCliVersion: '' # optional -- version of the CLI to send to Helix; based on this: https://raw.githubusercontent.com/dotnet/core/master/release-notes/releases.json
+ EnableXUnitReporter: false # optional -- true enables XUnit result reporting to Mission Control
+ WaitForWorkItemCompletion: true # optional -- true will make the task wait until work items have been completed and fail the build if work items fail. False is "fire and forget."
+ Creator: '' # optional -- if the build is external, use this to specify who is sending the job
+ DisplayNamePrefix: 'Send job to Helix' # optional -- rename the beginning of the displayName of the steps in AzDO
+ condition: succeeded() # optional -- condition for step to execute; defaults to succeeded()
+ continueOnError: false # optional -- determines whether to continue the build if the step errors; defaults to false
+
+steps:
+ - powershell: $(Build.SourcesDirectory)\eng\common\msbuild.ps1 $(Build.SourcesDirectory)\eng\common\performance\perfhelixpublish.proj /restore /t:Test /bl:$(Build.SourcesDirectory)\artifacts\log\$env:BuildConfig\SendToHelix.binlog
+ displayName: ${{ parameters.DisplayNamePrefix }} (Windows)
+ env:
+ BuildConfig: $(_BuildConfig)
+ HelixSource: ${{ parameters.HelixSource }}
+ HelixType: ${{ parameters.HelixType }}
+ HelixBuild: ${{ parameters.HelixBuild }}
+ HelixTargetQueues: ${{ parameters.HelixTargetQueues }}
+ HelixAccessToken: ${{ parameters.HelixAccessToken }}
+ HelixPreCommands: ${{ parameters.HelixPreCommands }}
+ HelixPostCommands: ${{ parameters.HelixPostCommands }}
+ WorkItemDirectory: ${{ parameters.WorkItemDirectory }}
+ CorrelationPayloadDirectory: ${{ parameters.CorrelationPayloadDirectory }}
+ IncludeDotNetCli: ${{ parameters.IncludeDotNetCli }}
+ DotNetCliPackageType: ${{ parameters.DotNetCliPackageType }}
+ DotNetCliVersion: ${{ parameters.DotNetCliVersion }}
+ EnableXUnitReporter: ${{ parameters.EnableXUnitReporter }}
+ WaitForWorkItemCompletion: ${{ parameters.WaitForWorkItemCompletion }}
+ Creator: ${{ parameters.Creator }}
+ SYSTEM_ACCESSTOKEN: $(System.AccessToken)
+ condition: and(${{ parameters.condition }}, eq(variables['Agent.Os'], 'Windows_NT'))
+ continueOnError: ${{ parameters.continueOnError }}
+ - script: $BUILD_SOURCESDIRECTORY/eng/common/msbuild.sh $BUILD_SOURCESDIRECTORY/eng/common/performance/perfhelixpublish.proj /restore /t:Test /bl:$BUILD_SOURCESDIRECTORY/artifacts/log/$BuildConfig/SendToHelix.binlog
+ displayName: ${{ parameters.DisplayNamePrefix }} (Unix)
+ env:
+ BuildConfig: $(_BuildConfig)
+ HelixSource: ${{ parameters.HelixSource }}
+ HelixType: ${{ parameters.HelixType }}
+ HelixBuild: ${{ parameters.HelixBuild }}
+ HelixTargetQueues: ${{ parameters.HelixTargetQueues }}
+ HelixAccessToken: ${{ parameters.HelixAccessToken }}
+ HelixPreCommands: ${{ parameters.HelixPreCommands }}
+ HelixPostCommands: ${{ parameters.HelixPostCommands }}
+ WorkItemDirectory: ${{ parameters.WorkItemDirectory }}
+ CorrelationPayloadDirectory: ${{ parameters.CorrelationPayloadDirectory }}
+ IncludeDotNetCli: ${{ parameters.IncludeDotNetCli }}
+ DotNetCliPackageType: ${{ parameters.DotNetCliPackageType }}
+ DotNetCliVersion: ${{ parameters.DotNetCliVersion }}
+ EnableXUnitReporter: ${{ parameters.EnableXUnitReporter }}
+ WaitForWorkItemCompletion: ${{ parameters.WaitForWorkItemCompletion }}
+ Creator: ${{ parameters.Creator }}
+ SYSTEM_ACCESSTOKEN: $(System.AccessToken)
+ condition: and(${{ parameters.condition }}, ne(variables['Agent.Os'], 'Windows_NT'))
+ continueOnError: ${{ parameters.continueOnError }}
diff --git a/eng/common/tools.ps1 b/eng/common/tools.ps1
index 60741f0390..9c12b1b4fd 100644
--- a/eng/common/tools.ps1
+++ b/eng/common/tools.ps1
@@ -39,6 +39,10 @@
# installed on the machine instead of downloading one.
[bool]$useInstalledDotNetCli = if (Test-Path variable:useInstalledDotNetCli) { $useInstalledDotNetCli } else { $true }
+# Enable repos to use a particular version of the on-line dotnet-install scripts.
+# default URL: https://dot.net/v1/dotnet-install.ps1
+[string]$dotnetInstallScriptVersion = if (Test-Path variable:dotnetInstallScriptVersion) { $dotnetInstallScriptVersion } else { "v1" }
+
# True to use global NuGet cache instead of restoring packages to repository-local directory.
[bool]$useGlobalNuGetCache = if (Test-Path variable:useGlobalNuGetCache) { $useGlobalNuGetCache } else { !$ci }
@@ -84,7 +88,7 @@ function Exec-Process([string]$command, [string]$commandArgs) {
return $global:LASTEXITCODE = $process.ExitCode
}
finally {
- # If we didn't finish then an error occured or the user hit ctrl-c. Either
+ # If we didn't finish then an error occurred or the user hit ctrl-c. Either
# way kill the process
if (-not $finished) {
$process.Kill()
@@ -147,7 +151,7 @@ function InitializeDotNetCli([bool]$install) {
# It also ensures that VS msbuild will use the downloaded sdk targets.
$env:PATH = "$dotnetRoot;$env:PATH"
- # Make Sure that our bootstrapped dotnet cli is avaliable in future steps of the Azure Pipelines build
+ # Make Sure that our bootstrapped dotnet cli is available 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'
@@ -159,7 +163,7 @@ function GetDotNetInstallScript([string] $dotnetRoot) {
$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
+ Invoke-WebRequest "https://dot.net/$dotnetInstallScriptVersion/dotnet-install.ps1" -OutFile $installScript
}
return $installScript
@@ -169,7 +173,7 @@ function InstallDotNetSdk([string] $dotnetRoot, [string] $version, [string] $arc
InstallDotNet $dotnetRoot $version $architecture
}
-function InstallDotNet([string] $dotnetRoot, [string] $version, [string] $architecture = "", [string] $runtime = "", [bool] $skipNonVersionedFiles = $false) { $installScript = GetDotNetInstallScript $dotnetRoot
+function InstallDotNet([string] $dotnetRoot, [string] $version, [string] $architecture = "", [string] $runtime = "", [bool] $skipNonVersionedFiles = $false) {
$installScript = GetDotNetInstallScript $dotnetRoot
$installParameters = @{
Version = $version
@@ -518,6 +522,9 @@ function MSBuild-Core() {
if ($warnAsError) {
$cmdArgs += " /warnaserror /p:TreatWarningsAsErrors=true"
}
+ else {
+ $cmdArgs += " /p:TreatWarningsAsErrors=false"
+ }
foreach ($arg in $args) {
if ($arg -ne $null -and $arg.Trim() -ne "") {
diff --git a/eng/common/tools.sh b/eng/common/tools.sh
old mode 100644
new mode 100755
index 70d92cf85a..3af9be6157
--- a/eng/common/tools.sh
+++ b/eng/common/tools.sh
@@ -45,6 +45,10 @@ warn_as_error=${warn_as_error:-true}
# installed on the machine instead of downloading one.
use_installed_dotnet_cli=${use_installed_dotnet_cli:-true}
+# Enable repos to use a particular version of the on-line dotnet-install scripts.
+# default URL: https://dot.net/v1/dotnet-install.sh
+dotnetInstallScriptVersion=${dotnetInstallScriptVersion:-'v1'}
+
# True to use global NuGet cache instead of restoring packages to repository-local directory.
if [[ "$ci" == true ]]; then
use_global_nuget_cache=${use_global_nuget_cache:-false}
@@ -77,7 +81,7 @@ function ReadGlobalVersion {
local pattern="\"$key\" *: *\"(.*)\""
if [[ ! $line =~ $pattern ]]; then
- Write-PipelineTelemetryError -category 'InitializeTools' "Error: Cannot find \"$key\" in $global_json_file"
+ Write-PipelineTelemetryError -category 'InitializeToolset' "Error: Cannot find \"$key\" in $global_json_file"
ExitWithExitCode 1
fi
@@ -146,14 +150,10 @@ function InitializeDotNetCli {
# Add dotnet to PATH. This prevents any bare invocation of dotnet in custom
# build steps from using anything other than what we've downloaded.
- export PATH="$dotnet_root:$PATH"
+ Write-PipelinePrependPath -path "$dotnet_root"
- if [[ $ci == true ]]; then
- # Make Sure that our bootstrapped dotnet cli is available in future steps of the Azure Pipelines build
- echo "##vso[task.prependpath]$dotnet_root"
- echo "##vso[task.setvariable variable=DOTNET_MULTILEVEL_LOOKUP]0"
- echo "##vso[task.setvariable variable=DOTNET_SKIP_FIRST_TIME_EXPERIENCE]1"
- fi
+ Write-PipelineSetVariable -name "DOTNET_MULTILEVEL_LOOKUP" -value "0"
+ Write-PipelineSetVariable -name "DOTNET_SKIP_FIRST_TIME_EXPERIENCE" -value "1"
# return value
_InitializeDotNetCli="$dotnet_root"
@@ -199,7 +199,7 @@ function InstallDotNet {
function GetDotNetInstallScript {
local root=$1
local install_script="$root/dotnet-install.sh"
- local install_script_url="https://dot.net/v1/dotnet-install.sh"
+ local install_script_url="https://dot.net/$dotnetInstallScriptVersion/dotnet-install.sh"
if [[ ! -a "$install_script" ]]; then
mkdir -p "$root"
@@ -249,7 +249,7 @@ function InitializeNativeTools() {
then
local nativeArgs=""
if [[ "$ci" == true ]]; then
- nativeArgs="-InstallDirectory $tools_dir"
+ nativeArgs="--installDirectory $tools_dir"
fi
"$_script_dir/init-tools-native.sh" $nativeArgs
fi
@@ -387,7 +387,8 @@ mkdir -p "$toolset_dir"
mkdir -p "$temp_dir"
mkdir -p "$log_dir"
-if [[ $ci == true ]]; then
- export TEMP="$temp_dir"
- export TMP="$temp_dir"
-fi
+Write-PipelineSetVariable -name "Artifacts" -value "$artifacts_dir"
+Write-PipelineSetVariable -name "Artifacts.Toolset" -value "$toolset_dir"
+Write-PipelineSetVariable -name "Artifacts.Log" -value "$log_dir"
+Write-PipelineSetVariable -name "Temp" -value "$temp_dir"
+Write-PipelineSetVariable -name "TMP" -value "$temp_dir"
diff --git a/eng/targets/Settings.props b/eng/targets/Settings.props
index 5d145af11c..3290288182 100644
--- a/eng/targets/Settings.props
+++ b/eng/targets/Settings.props
@@ -2,13 +2,13 @@
MIT
- Microsoft and F# Software Foundation
Visual F# Compiler FSharp functional programming
$(ArtifactsBinDir)
- true
+
+ false
diff --git a/fcs/Directory.Build.props b/fcs/Directory.Build.props
index dc1615654c..7988ee2f36 100644
--- a/fcs/Directory.Build.props
+++ b/fcs/Directory.Build.props
@@ -31,7 +31,6 @@
$(FSharpSourcesRoot)\..\packages\FSharp.Compiler.Tools.4.1.27\tools
fsi.exe
- $(ArtifactsBinDir)\FSharp.Build\Proto\net472
4.6.2
net461
diff --git a/fcs/FSharp.Compiler.Service.Tests/QuickInfoTests.fs b/fcs/FSharp.Compiler.Service.Tests/QuickInfoTests.fs
index bfa6c7df72..415079942e 100644
--- a/fcs/FSharp.Compiler.Service.Tests/QuickInfoTests.fs
+++ b/fcs/FSharp.Compiler.Service.Tests/QuickInfoTests.fs
@@ -154,9 +154,9 @@ module Test =
let quickInfo = GetQuickInfoTextFromCode code
let expected =
expectedLines [ "type MyEmployee ="
- " {mutable Name: string;"
- " mutable Age: int;"
- " mutable IsFTE: bool;}"
+ " { mutable Name: string"
+ " mutable Age: int"
+ " mutable IsFTE: bool }"
"Full name: FsTest.MyEmployee" ]
Assert.AreEqual(expected, quickInfo)
()
diff --git a/fcs/FSharp.Compiler.Service/FSharp.Compiler.Service.fsproj b/fcs/FSharp.Compiler.Service/FSharp.Compiler.Service.fsproj
index 33188f095d..55b2ad535e 100644
--- a/fcs/FSharp.Compiler.Service/FSharp.Compiler.Service.fsproj
+++ b/fcs/FSharp.Compiler.Service/FSharp.Compiler.Service.fsproj
@@ -1,4 +1,4 @@
-
+
$(MSBuildProjectDirectory)\..\..\src
diff --git a/fcs/RELEASE_NOTES.md b/fcs/RELEASE_NOTES.md
index 35476348dd..73164bb892 100644
--- a/fcs/RELEASE_NOTES.md
+++ b/fcs/RELEASE_NOTES.md
@@ -1,3 +1,15 @@
+#### 31.0.0
+ * Integrate dotnet/fsharp from 5a8f454a1 to 05c558a61
+ * Notable changes include:
+ * Removal of the `Microsoft.FSharp.Compiler.SourceCodeServices` namespace
+ * A new API for determining if an identifier needs to be quoted is available: `FSharp.Compiler.LexHelp.Keywords.DoesIdentifierNeedQuotation`
+ * Enhancements to the correctness of PDBs
+ * Better string formatting of records and values
+ * More stack overflow fixes in the compiler
+ * Inline IL parsing error handling
+ * `LeafExpressionConverter` handles struct tuples
+ * `FSharpChecker` now can parse a file without caching: `ParseFileNoCache`
+
#### 30.0.0
* Integrate dotnet/fsharp from 25560f477 to 5a8f454a1
* Notable improvements include:
@@ -5,7 +17,6 @@
* FCS APIs for FSComp and Implement Interface
* line directive handling
* improved performance when computing quick fix suggestions
-
#### 29.0.1
* Fix versioning of the assembly
diff --git a/fcs/download-paket.ps1 b/fcs/download-paket.ps1
index 7aa8c5ef6f..4541168012 100644
--- a/fcs/download-paket.ps1
+++ b/fcs/download-paket.ps1
@@ -1,4 +1,4 @@
-$paketurl="https://github.com/fsprojects/Paket/releases/download/5.210.1/paket.exe"
+$paketurl="https://github.com/fsprojects/Paket/releases/download/5.215.0/paket.exe"
$paketdir = Join-Path $PSScriptRoot ".paket"
$paketpath = Join-Path $paketdir "paket.exe"
diff --git a/fcs/download-paket.sh b/fcs/download-paket.sh
index d2bf8524a8..2825ac4d5a 100755
--- a/fcs/download-paket.sh
+++ b/fcs/download-paket.sh
@@ -12,7 +12,7 @@ while [[ -h "$source" ]]; do
done
scriptroot="$( cd -P "$( dirname "$source" )" && pwd )"
-paketurl=https://github.com/fsprojects/Paket/releases/download/5.210.1/paket.exe
+paketurl=https://github.com/fsprojects/Paket/releases/download/5.215.0/paket.exe
paketdir=$scriptroot/.paket
paketpath=$paketdir/paket.exe
if [ ! -e "$paketpath" ]; then
diff --git a/global.json b/global.json
index 1f44c774f6..42b7fded08 100644
--- a/global.json
+++ b/global.json
@@ -1,6 +1,6 @@
{
"tools": {
- "dotnet": "3.0.100-preview5-011568",
+ "dotnet": "3.0.100-preview6-012264",
"vs": {
"version": "16.1",
"components": [
@@ -10,7 +10,7 @@
}
},
"msbuild-sdks": {
- "Microsoft.DotNet.Arcade.Sdk": "1.0.0-beta.19323.4",
+ "Microsoft.DotNet.Arcade.Sdk": "1.0.0-beta.19410.2",
"Microsoft.DotNet.Helix.Sdk": "2.0.0-beta.19069.2"
}
}
diff --git a/proto.proj b/proto.proj
index b94fb70481..23d7525d13 100644
--- a/proto.proj
+++ b/proto.proj
@@ -25,6 +25,10 @@
+
+
+
+
diff --git a/src/absil/ilreflect.fs b/src/absil/ilreflect.fs
index f1afa06c48..fa49d64c9e 100755
--- a/src/absil/ilreflect.fs
+++ b/src/absil/ilreflect.fs
@@ -327,6 +327,8 @@ type cenv =
generatePdb: bool
resolveAssemblyRef: (ILAssemblyRef -> Choice option) }
+ override x.ToString() = ""
+
/// Convert an Abstract IL type reference to Reflection.Emit System.Type value.
// This ought to be an adequate substitute for this whole function, but it needs
// to be thoroughly tested.
diff --git a/src/absil/ilwrite.fs b/src/absil/ilwrite.fs
index e48c00eaf0..e9978c3de5 100755
--- a/src/absil/ilwrite.fs
+++ b/src/absil/ilwrite.fs
@@ -605,6 +605,7 @@ type cenv =
member cenv.GetCode() = cenv.codeChunks.Close()
+ override x.ToString() = ""
let FindOrAddSharedRow (cenv: cenv) tbl x = cenv.GetTable(tbl).FindOrAddSharedEntry x
@@ -3025,7 +3026,8 @@ let generateIL requiredDataFixups (desiredMetadataVersion, generatePdb, ilg : IL
//=====================================================================
// TABLES+BLOBS --> PHYSICAL METADATA+BLOBS
//=====================================================================
-let chunk sz next = ({addr=next; size=sz}, next + sz)
+let chunk sz next = ({addr=next; size=sz}, next + sz)
+let emptychunk next = ({addr=next; size=0}, next)
let nochunk next = ({addr= 0x0;size= 0x0; }, next)
let count f arr =
@@ -3516,7 +3518,7 @@ let writeBytes (os: BinaryWriter) (chunk: byte[]) = os.Write(chunk, 0, chunk.Len
let writeBinaryAndReportMappings (outfile,
ilg: ILGlobals, pdbfile: string option, signer: ILStrongNameSigner option, portablePDB, embeddedPDB,
- embedAllSource, embedSourceList, sourceLink, emitTailcalls, deterministic, showTimes, dumpDebugInfo, pathMap)
+ embedAllSource, embedSourceList, sourceLink, checksumAlgorithm, emitTailcalls, deterministic, showTimes, dumpDebugInfo, pathMap)
modul normalizeAssemblyRefs =
// Store the public key from the signer into the manifest. This means it will be written
// to the binary and also acts as an indicator to leave space for delay sign
@@ -3565,7 +3567,7 @@ let writeBinaryAndReportMappings (outfile,
with e ->
failwith ("Could not open file for writing (binary mode): " + outfile)
- let pdbData, pdbOpt, debugDirectoryChunk, debugDataChunk, debugEmbeddedPdbChunk, textV2P, mappings =
+ let pdbData, pdbOpt, debugDirectoryChunk, debugDataChunk, debugChecksumPdbChunk, debugEmbeddedPdbChunk, debugDeterministicPdbChunk, textV2P, mappings =
try
let imageBaseReal = modul.ImageBase // FIXED CHOICE
@@ -3670,42 +3672,61 @@ let writeBinaryAndReportMappings (outfile,
let pdbOpt =
match portablePDB with
| true ->
- let (uncompressedLength, contentId, stream) as pdbStream =
- generatePortablePdb embedAllSource embedSourceList sourceLink showTimes pdbData deterministic pathMap
+ let (uncompressedLength, contentId, stream, algorithmName, checkSum) as pdbStream =
+ generatePortablePdb embedAllSource embedSourceList sourceLink checksumAlgorithm showTimes pdbData pathMap
- if embeddedPDB then Some (compressPortablePdbStream uncompressedLength contentId stream)
+ if embeddedPDB then
+ let uncompressedLength, contentId, stream = compressPortablePdbStream uncompressedLength contentId stream
+ Some (uncompressedLength, contentId, stream, algorithmName, checkSum)
else Some pdbStream
| _ -> None
- let debugDirectoryChunk, next =
- chunk (if pdbfile = None then
- 0x0
- else if embeddedPDB && portablePDB then
- sizeof_IMAGE_DEBUG_DIRECTORY * 2
+ let debugDirectoryChunk, next =
+ chunk (if pdbfile = None then
+ 0x0
else
- sizeof_IMAGE_DEBUG_DIRECTORY
+ sizeof_IMAGE_DEBUG_DIRECTORY * 2 +
+ (if embeddedPDB then sizeof_IMAGE_DEBUG_DIRECTORY else 0) +
+ (if deterministic then sizeof_IMAGE_DEBUG_DIRECTORY else 0)
) next
+
// The debug data is given to us by the PDB writer and appears to
// typically be the type of the data plus the PDB file name. We fill
// this in after we've written the binary. We approximate the size according
// to what PDB writers seem to require and leave extra space just in case...
let debugDataJustInCase = 40
- let debugDataChunk, next =
+ let debugDataChunk, next =
chunk (align 0x4 (match pdbfile with
| None -> 0
| Some f -> (24
+ System.Text.Encoding.Unicode.GetByteCount f // See bug 748444
+ debugDataJustInCase))) next
- let debugEmbeddedPdbChunk, next =
- let streamLength =
- match pdbOpt with
- | Some (_, _, stream) -> int stream.Length
- | None -> 0
- chunk (align 0x4 (match embeddedPDB with
- | true -> 8 + streamLength
- | _ -> 0 )) next
+ let debugChecksumPdbChunk, next =
+ chunk (align 0x4 (match pdbOpt with
+ | Some (_, _, _, algorithmName, checkSum) ->
+ let alg = System.Text.Encoding.UTF8.GetBytes(algorithmName)
+ let size = alg.Length + 1 + checkSum.Length
+ size
+ | None -> 0)) next
+
+ let debugEmbeddedPdbChunk, next =
+ if embeddedPDB then
+ let streamLength =
+ match pdbOpt with
+ | Some (_, _, stream, _, _) -> int stream.Length
+ | None -> 0
+ chunk (align 0x4 (match embeddedPDB with
+ | true -> 8 + streamLength
+ | _ -> 0 )) next
+ else
+ nochunk next
+
+ let debugDeterministicPdbChunk, next =
+ if deterministic then emptychunk next
+ else nochunk next
+
let textSectionSize = next - textSectionAddr
let nextPhys = align alignPhys (textSectionPhysLoc + textSectionSize)
@@ -3804,35 +3825,39 @@ let writeBinaryAndReportMappings (outfile,
if pCurrent <> pExpected then
failwith ("warning: "+chunkName+" not where expected, pCurrent = "+string pCurrent+", p.addr = "+string pExpected)
writeBytes os chunk
-
+
let writePadding (os: BinaryWriter) _comment sz =
if sz < 0 then failwith "writePadding: size < 0"
for i = 0 to sz - 1 do
os.Write 0uy
-
+
// Now we've computed all the offsets, write the image
-
+
write (Some msdosHeaderChunk.addr) os "msdos header" msdosHeader
-
+
write (Some peSignatureChunk.addr) os "pe signature" [| |]
-
+
writeInt32 os 0x4550
-
+
write (Some peFileHeaderChunk.addr) os "pe file header" [| |]
-
+
if (modul.Platform = Some AMD64) then
writeInt32AsUInt16 os 0x8664 // Machine - IMAGE_FILE_MACHINE_AMD64
elif isItanium then
writeInt32AsUInt16 os 0x200
else
writeInt32AsUInt16 os 0x014c // Machine - IMAGE_FILE_MACHINE_I386
-
+
writeInt32AsUInt16 os numSections
- let pdbData =
+ let pdbData =
+ // Hash code, data and metadata
if deterministic then
- // Hash code, data and metadata
- use sha = System.Security.Cryptography.SHA1.Create() // IncrementalHash is core only
+ use sha =
+ match checksumAlgorithm with
+ | HashAlgorithm.Sha1 -> System.Security.Cryptography.SHA1.Create() :> System.Security.Cryptography.HashAlgorithm
+ | HashAlgorithm.Sha256 -> System.Security.Cryptography.SHA256.Create() :> System.Security.Cryptography.HashAlgorithm
+
let hCode = sha.ComputeHash code
let hData = sha.ComputeHash data
let hMeta = sha.ComputeHash metadata
@@ -3848,6 +3873,7 @@ let writeBinaryAndReportMappings (outfile,
// Use last 4 bytes for timestamp - High bit set, to stop tool chains becoming confused
let timestamp = int final.[16] ||| (int final.[17] <<< 8) ||| (int final.[18] <<< 16) ||| (int (final.[19] ||| 128uy) <<< 24)
writeInt32 os timestamp
+
// Update pdbData with new guid and timestamp. Portable and embedded PDBs don't need the ModuleID
// Full and PdbOnly aren't supported under deterministic builds currently, they rely on non-determinsitic Windows native code
{ pdbData with ModuleID = final.[0..15] ; Timestamp = timestamp }
@@ -4133,10 +4159,14 @@ let writeBinaryAndReportMappings (outfile,
if pdbfile.IsSome then
write (Some (textV2P debugDirectoryChunk.addr)) os "debug directory" (Array.create debugDirectoryChunk.size 0x0uy)
write (Some (textV2P debugDataChunk.addr)) os "debug data" (Array.create debugDataChunk.size 0x0uy)
+ write (Some (textV2P debugChecksumPdbChunk.addr)) os "debug checksum" (Array.create debugChecksumPdbChunk.size 0x0uy)
if embeddedPDB then
write (Some (textV2P debugEmbeddedPdbChunk.addr)) os "debug data" (Array.create debugEmbeddedPdbChunk.size 0x0uy)
+ if deterministic then
+ write (Some (textV2P debugDeterministicPdbChunk.addr)) os "debug deterministic" Array.empty
+
writePadding os "end of .text" (dataSectionPhysLoc - textSectionPhysLoc - textSectionSize)
// DATA SECTION
@@ -4182,7 +4212,7 @@ let writeBinaryAndReportMappings (outfile,
FileSystemUtilites.setExecutablePermission outfile
with _ ->
()
- pdbData, pdbOpt, debugDirectoryChunk, debugDataChunk, debugEmbeddedPdbChunk, textV2P, mappings
+ pdbData, pdbOpt, debugDirectoryChunk, debugDataChunk, debugChecksumPdbChunk, debugEmbeddedPdbChunk, debugDeterministicPdbChunk, textV2P, mappings
// Looks like a finally
with e ->
@@ -4207,11 +4237,11 @@ let writeBinaryAndReportMappings (outfile,
try
let idd =
match pdbOpt with
- | Some (originalLength, contentId, stream) ->
+ | Some (originalLength, contentId, stream, algorithmName, checkSum) ->
if embeddedPDB then
- embedPortablePdbInfo originalLength contentId stream showTimes fpdb debugDataChunk debugEmbeddedPdbChunk
+ embedPortablePdbInfo originalLength contentId stream showTimes fpdb debugDataChunk debugEmbeddedPdbChunk debugDeterministicPdbChunk debugChecksumPdbChunk algorithmName checkSum embeddedPDB deterministic
else
- writePortablePdbInfo contentId stream showTimes fpdb pathMap debugDataChunk
+ writePortablePdbInfo contentId stream showTimes fpdb pathMap debugDataChunk debugDeterministicPdbChunk debugChecksumPdbChunk algorithmName checkSum embeddedPDB deterministic
| None ->
#if FX_NO_PDB_WRITER
Array.empty
@@ -4232,16 +4262,17 @@ let writeBinaryAndReportMappings (outfile,
writeInt32AsUInt16 os2 i.iddMajorVersion
writeInt32AsUInt16 os2 i.iddMinorVersion
writeInt32 os2 i.iddType
- writeInt32 os2 i.iddData.Length // IMAGE_DEBUG_DIRECTORY.SizeOfData
- writeInt32 os2 i.iddChunk.addr // IMAGE_DEBUG_DIRECTORY.AddressOfRawData
- writeInt32 os2 (textV2P i.iddChunk.addr) // IMAGE_DEBUG_DIRECTORY.PointerToRawData
+ writeInt32 os2 i.iddData.Length // IMAGE_DEBUG_DIRECTORY.SizeOfData
+ writeInt32 os2 i.iddChunk.addr // IMAGE_DEBUG_DIRECTORY.AddressOfRawData
+ writeInt32 os2 (textV2P i.iddChunk.addr) // IMAGE_DEBUG_DIRECTORY.PointerToRawData
// Write the Debug Data
for i in idd do
- // write the debug raw data as given us by the PDB writer
- os2.BaseStream.Seek (int64 (textV2P i.iddChunk.addr), SeekOrigin.Begin) |> ignore
- if i.iddChunk.size < i.iddData.Length then failwith "Debug data area is not big enough. Debug info may not be usable"
- writeBytes os2 i.iddData
+ if i.iddChunk.size <> 0 then
+ // write the debug raw data as given us by the PDB writer
+ os2.BaseStream.Seek (int64 (textV2P i.iddChunk.addr), SeekOrigin.Begin) |> ignore
+ if i.iddChunk.size < i.iddData.Length then failwith "Debug data area is not big enough. Debug info may not be usable"
+ writeBytes os2 i.iddData
os2.Dispose()
with e ->
failwith ("Error while writing debug directory entry: "+e.Message)
@@ -4250,9 +4281,7 @@ let writeBinaryAndReportMappings (outfile,
with e ->
reraise()
- end
- ignore debugDataChunk
- ignore debugEmbeddedPdbChunk
+ end
reportTime showTimes "Finalize PDB"
/// Sign the binary. No further changes to binary allowed past this point!
@@ -4280,9 +4309,10 @@ type options =
embedAllSource: bool
embedSourceList: string list
sourceLink: string
+ checksumAlgorithm: HashAlgorithm
signer: ILStrongNameSigner option
- emitTailcalls : bool
- deterministic : bool
+ emitTailcalls: bool
+ deterministic: bool
showTimes: bool
dumpDebugInfo: bool
pathMap: PathMap }
@@ -4290,5 +4320,5 @@ type options =
let WriteILBinary (outfile, (args: options), modul, normalizeAssemblyRefs) =
writeBinaryAndReportMappings (outfile,
args.ilg, args.pdbfile, args.signer, args.portablePDB, args.embeddedPDB, args.embedAllSource,
- args.embedSourceList, args.sourceLink, args.emitTailcalls, args.deterministic, args.showTimes, args.dumpDebugInfo, args.pathMap) modul normalizeAssemblyRefs
+ args.embedSourceList, args.sourceLink, args.checksumAlgorithm, args.emitTailcalls, args.deterministic, args.showTimes, args.dumpDebugInfo, args.pathMap) modul normalizeAssemblyRefs
|> ignore
diff --git a/src/absil/ilwrite.fsi b/src/absil/ilwrite.fsi
index f1955f82a2..9dba89c9b6 100755
--- a/src/absil/ilwrite.fsi
+++ b/src/absil/ilwrite.fsi
@@ -1,12 +1,13 @@
// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information.
/// The IL Binary writer.
-module internal FSharp.Compiler.AbstractIL.ILBinaryWriter
+module internal FSharp.Compiler.AbstractIL.ILBinaryWriter
open Internal.Utilities
-open FSharp.Compiler.AbstractIL
-open FSharp.Compiler.AbstractIL.Internal
-open FSharp.Compiler.AbstractIL.IL
+open FSharp.Compiler.AbstractIL
+open FSharp.Compiler.AbstractIL.Internal
+open FSharp.Compiler.AbstractIL.IL
+open FSharp.Compiler.AbstractIL.ILPdbWriter
[]
type ILStrongNameSigner =
@@ -24,6 +25,7 @@ type options =
embedAllSource: bool
embedSourceList: string list
sourceLink: string
+ checksumAlgorithm: HashAlgorithm
signer : ILStrongNameSigner option
emitTailcalls: bool
deterministic: bool
diff --git a/src/absil/ilwritepdb.fs b/src/absil/ilwritepdb.fs
index 260ccbe238..86b7ee9224 100644
--- a/src/absil/ilwritepdb.fs
+++ b/src/absil/ilwritepdb.fs
@@ -11,8 +11,9 @@ open System.Reflection
open System.Reflection.Metadata
open System.Reflection.Metadata.Ecma335
open System.Reflection.PortableExecutable
+open System.Text
open Internal.Utilities
-open FSharp.Compiler.AbstractIL.IL
+open FSharp.Compiler.AbstractIL.IL
open FSharp.Compiler.AbstractIL.Diagnostics
open FSharp.Compiler.AbstractIL.Internal.Support
open FSharp.Compiler.AbstractIL.Internal.Library
@@ -125,6 +126,27 @@ type idd =
iddData: byte[]
iddChunk: BinaryChunk }
+/// The specified Hash algorithm to use on portable pdb files.
+type HashAlgorithm =
+ | Sha1
+ | Sha256
+
+// Document checksum algorithms
+let guidSha1 = Guid("ff1816ec-aa5e-4d10-87f7-6f4963833460")
+let guidSha2 = Guid("8829d00f-11b8-4213-878b-770e8597ac16")
+
+let checkSum (url: string) (checksumAlgorithm: HashAlgorithm) =
+ try
+ use file = FileSystem.FileStreamReadShim url
+ let guid, alg =
+ match checksumAlgorithm with
+ | HashAlgorithm.Sha1 -> guidSha1, System.Security.Cryptography.SHA1.Create() :> System.Security.Cryptography.HashAlgorithm
+ | HashAlgorithm.Sha256 -> guidSha2, System.Security.Cryptography.SHA256.Create() :> System.Security.Cryptography.HashAlgorithm
+
+ let checkSum = alg.ComputeHash file
+ Some (guid, checkSum)
+ with _ -> None
+
//---------------------------------------------------------------------
// Portable PDB Writer
//---------------------------------------------------------------------
@@ -153,7 +175,7 @@ let pdbGetCvDebugInfo (mvid: byte[]) (timestamp: int32) (filepath: string) (cvCh
}
let pdbMagicNumber= 0x4244504dL
-let pdbGetPdbDebugInfo (embeddedPDBChunk: BinaryChunk) (uncompressedLength: int64) (stream: MemoryStream) =
+let pdbGetEmbeddedPdbDebugInfo (embeddedPdbChunk: BinaryChunk) (uncompressedLength: int64) (stream: MemoryStream) =
let iddPdbBuffer =
let buffer = Array.zeroCreate (sizeof + sizeof + int(stream.Length))
let (offset, size) = (0, sizeof) // Magic Number dword: 0x4244504dL
@@ -164,33 +186,57 @@ let pdbGetPdbDebugInfo (embeddedPDBChunk: BinaryChunk) (uncompressedLength: int6
Buffer.BlockCopy(stream.ToArray(), 0, buffer, offset, size)
buffer
{ iddCharacteristics = 0 // Reserved
- iddMajorVersion = 0 // VersionMajor should be 0
+ iddMajorVersion = 0x0100 // VersionMajor should be 0x0100
iddMinorVersion = 0x0100 // VersionMinor should be 0x0100
iddType = 17 // IMAGE_DEBUG_TYPE_EMBEDDEDPDB
iddTimestamp = 0
iddData = iddPdbBuffer // Path name to the pdb file when built
- iddChunk = embeddedPDBChunk
+ iddChunk = embeddedPdbChunk
}
-let pdbGetDebugInfo (mvid: byte[]) (timestamp: int32) (filepath: string) (cvChunk: BinaryChunk) (embeddedPDBChunk: BinaryChunk option) (uncompressedLength: int64) (stream: MemoryStream option) =
- match stream, embeddedPDBChunk with
- | None, _ | _, None -> [| pdbGetCvDebugInfo mvid timestamp filepath cvChunk |]
- | Some s, Some chunk -> [| pdbGetCvDebugInfo mvid timestamp filepath cvChunk; pdbGetPdbDebugInfo chunk uncompressedLength s |]
+let pdbChecksumDebugInfo timestamp (checksumPdbChunk: BinaryChunk) (algorithmName:string) (checksum: byte[]) =
+ let iddBuffer =
+ let alg = Encoding.UTF8.GetBytes(algorithmName)
+ let buffer = Array.zeroCreate (alg.Length + 1 + checksum.Length)
+ Buffer.BlockCopy(alg, 0, buffer, 0, alg.Length)
+ Buffer.BlockCopy(checksum, 0, buffer, alg.Length + 1, checksum.Length)
+ buffer
+ { iddCharacteristics = 0 // Reserved
+ iddMajorVersion = 1 // VersionMajor should be 1
+ iddMinorVersion = 0x0100 // VersionMinor should be 0x0100
+ iddType = 19 // IMAGE_DEBUG_TYPE_CHECKSUMPDB
+ iddTimestamp = timestamp
+ iddData = iddBuffer // Path name to the pdb file when built
+ iddChunk = checksumPdbChunk
+ }
-// Document checksum algorithms
-let guidSourceHashMD5 = System.Guid(0x406ea660u, 0x64cfus, 0x4c82us, 0xb6uy, 0xf0uy, 0x42uy, 0xd4uy, 0x81uy, 0x72uy, 0xa7uy, 0x99uy) //406ea660-64cf-4c82-b6f0-42d48172a799
-let hashSizeOfMD5 = 16
+let pdbGetPdbDebugDeterministicInfo (deterministicPdbChunk: BinaryChunk) =
+ { iddCharacteristics = 0 // Reserved
+ iddMajorVersion = 0 // VersionMajor should be 0
+ iddMinorVersion = 0 // VersionMinor should be 00
+ iddType = 16 // IMAGE_DEBUG_TYPE_DETERMINISTIC
+ iddTimestamp = 0
+ iddData = Array.empty // No DATA
+ iddChunk = deterministicPdbChunk
+ }
-// If the FIPS algorithm policy is enabled on the computer (e.g., for US government employees and contractors)
-// then obtaining the MD5 implementation in BCL will throw.
-// In this case, catch the failure, and not set a checksum.
-let checkSum (url: string) =
- try
- use file = FileSystem.FileStreamReadShim url
- use md5 = System.Security.Cryptography.MD5.Create()
- let checkSum = md5.ComputeHash file
- Some (guidSourceHashMD5, checkSum)
- with _ -> None
+let pdbGetDebugInfo (contentId: byte[]) (timestamp: int32) (filepath: string)
+ (cvChunk: BinaryChunk)
+ (embeddedPdbChunk: BinaryChunk option)
+ (deterministicPdbChunk: BinaryChunk)
+ (checksumPdbChunk: BinaryChunk) (algorithmName:string) (checksum: byte [])
+ (uncompressedLength: int64) (stream: MemoryStream option)
+ (embeddedPdb: bool) (deterministic: bool) =
+ [| yield pdbGetCvDebugInfo contentId timestamp filepath cvChunk
+ yield pdbChecksumDebugInfo timestamp checksumPdbChunk algorithmName checksum
+ if embeddedPdb then
+ match stream, embeddedPdbChunk with
+ | None, _ | _, None -> ()
+ | Some s, Some chunk ->
+ yield pdbGetEmbeddedPdbDebugInfo chunk uncompressedLength s
+ if deterministic then
+ yield pdbGetPdbDebugDeterministicInfo deterministicPdbChunk
+ |]
//------------------------------------------------------------------------------
// PDB Writer. The function [WritePdbInfo] abstracts the
@@ -219,7 +265,7 @@ let getRowCounts tableRowCounts =
tableRowCounts |> Seq.iter(fun x -> builder.Add x)
builder.MoveToImmutable()
-let generatePortablePdb (embedAllSource: bool) (embedSourceList: string list) (sourceLink: string) showTimes (info: PdbData) isDeterministic (pathMap: PathMap) =
+let generatePortablePdb (embedAllSource: bool) (embedSourceList: string list) (sourceLink: string) checksumAlgorithm showTimes (info: PdbData) (pathMap: PathMap) =
sortMethods showTimes info
let externalRowCounts = getRowCounts info.TableRowCounts
let docs =
@@ -286,7 +332,7 @@ let generatePortablePdb (embedAllSource: bool) (embedSourceList: string list) (s
metadata.SetCapacity(TableIndex.Document, docLength)
for doc in docs do
let handle =
- match checkSum doc.File with
+ match checkSum doc.File checksumAlgorithm with
| Some (hashAlg, checkSum) ->
let dbgInfo =
(serializeDocumentName doc.File,
@@ -403,12 +449,17 @@ let generatePortablePdb (embedAllSource: bool) (embedSourceList: string list) (s
if i < 1 || offsetDelta > 0 then
builder.WriteCompressedInteger offsetDelta
- // Hidden-sequence-point-record
- if startLine = 0xfeefee || endLine = 0xfeefee || (startColumn = 0 && endColumn = 0)
+ // Check for hidden-sequence-point-record
+ if startLine = 0xfeefee ||
+ endLine = 0xfeefee ||
+ (startColumn = 0 && endColumn = 0) ||
+ ((endLine - startLine) = 0 && (endColumn - startColumn) = 0)
then
+ // Hidden-sequence-point-record
builder.WriteCompressedInteger 0
builder.WriteCompressedInteger 0
- else // Non-hidden-sequence-point-record
+ else
+ // Non-hidden-sequence-point-record
let deltaLines = endLine - startLine // lines
builder.WriteCompressedInteger deltaLines
@@ -476,25 +527,28 @@ let generatePortablePdb (embedAllSource: bool) (embedSourceList: string list) (s
| None -> MetadataTokens.MethodDefinitionHandle 0
| Some x -> MetadataTokens.MethodDefinitionHandle x
- let deterministicIdProvider isDeterministic : System.Func, BlobContentId> =
- match isDeterministic with
- | false -> null
- | true ->
- let convert (content: IEnumerable) =
- use sha = System.Security.Cryptography.SHA1.Create() // IncrementalHash is core only
- let hash = content
- |> Seq.collect (fun c -> c.GetBytes().Array |> sha.ComputeHash)
- |> Array.ofSeq |> sha.ComputeHash
- BlobContentId.FromHash hash
- System.Func, BlobContentId>( convert )
-
- let serializer = PortablePdbBuilder(metadata, externalRowCounts, entryPoint, deterministicIdProvider isDeterministic)
+ // Compute the contentId for the pdb. Always do it deterministically, since we have to compute the anyway.
+ // The contentId is the hash of the ID using whichever algorithm has been specified to the compiler
+ let mutable contentHash = Array.empty
+
+ let algorithmName, hashAlgorithm =
+ match checksumAlgorithm with
+ | HashAlgorithm.Sha1 -> "SHA1", System.Security.Cryptography.SHA1.Create() :> System.Security.Cryptography.HashAlgorithm
+ | HashAlgorithm.Sha256 -> "SHA256", System.Security.Cryptography.SHA256.Create() :> System.Security.Cryptography.HashAlgorithm
+ let idProvider: System.Func, BlobContentId> =
+ let convert (content: IEnumerable) =
+ let contentBytes = content |> Seq.collect (fun c -> c.GetBytes()) |> Array.ofSeq
+ contentHash <- contentBytes |> hashAlgorithm.ComputeHash
+ BlobContentId.FromHash contentHash
+ System.Func, BlobContentId>(convert)
+
+ let serializer = PortablePdbBuilder(metadata, externalRowCounts, entryPoint, idProvider)
let blobBuilder = new BlobBuilder()
let contentId= serializer.Serialize blobBuilder
let portablePdbStream = new MemoryStream()
blobBuilder.WriteContentTo portablePdbStream
reportTime showTimes "PDB: Created"
- (portablePdbStream.Length, contentId, portablePdbStream)
+ (portablePdbStream.Length, contentId, portablePdbStream, algorithmName, contentHash)
let compressPortablePdbStream (uncompressedLength: int64) (contentId: BlobContentId) (stream: MemoryStream) =
let compressedStream = new MemoryStream()
@@ -502,17 +556,17 @@ let compressPortablePdbStream (uncompressedLength: int64) (contentId: BlobConten
stream.WriteTo compressionStream
(uncompressedLength, contentId, compressedStream)
-let writePortablePdbInfo (contentId: BlobContentId) (stream: MemoryStream) showTimes fpdb pathMap cvChunk =
+let writePortablePdbInfo (contentId: BlobContentId) (stream: MemoryStream) showTimes fpdb pathMap cvChunk deterministicPdbChunk checksumPdbChunk algName checksum embeddedPdb deterministicPdb =
try FileSystem.FileDelete fpdb with _ -> ()
use pdbFile = new FileStream(fpdb, FileMode.Create, FileAccess.ReadWrite)
stream.WriteTo pdbFile
reportTime showTimes "PDB: Closed"
- pdbGetDebugInfo (contentId.Guid.ToByteArray()) (int32 (contentId.Stamp)) (PathMap.apply pathMap fpdb) cvChunk None 0L None
+ pdbGetDebugInfo (contentId.Guid.ToByteArray()) (int32 (contentId.Stamp)) (PathMap.apply pathMap fpdb) cvChunk None deterministicPdbChunk checksumPdbChunk algName checksum 0L None embeddedPdb deterministicPdb
-let embedPortablePdbInfo (uncompressedLength: int64) (contentId: BlobContentId) (stream: MemoryStream) showTimes fpdb cvChunk pdbChunk =
+let embedPortablePdbInfo (uncompressedLength: int64) (contentId: BlobContentId) (stream: MemoryStream) showTimes fpdb cvChunk pdbChunk deterministicPdbChunk checksumPdbChunk algName checksum embeddedPdb deterministicPdb =
reportTime showTimes "PDB: Closed"
let fn = Path.GetFileName fpdb
- pdbGetDebugInfo (contentId.Guid.ToByteArray()) (int32 (contentId.Stamp)) fn cvChunk (Some pdbChunk) uncompressedLength (Some stream)
+ pdbGetDebugInfo (contentId.Guid.ToByteArray()) (int32 (contentId.Stamp)) fn cvChunk (Some pdbChunk) deterministicPdbChunk checksumPdbChunk algName checksum uncompressedLength (Some stream) embeddedPdb deterministicPdb
#if !FX_NO_PDB_WRITER
//---------------------------------------------------------------------
diff --git a/src/absil/ilwritepdb.fsi b/src/absil/ilwritepdb.fsi
index 2713d9769b..748e178a46 100644
--- a/src/absil/ilwritepdb.fsi
+++ b/src/absil/ilwritepdb.fsi
@@ -4,7 +4,7 @@
module internal FSharp.Compiler.AbstractIL.ILPdbWriter
open Internal.Utilities
-open FSharp.Compiler.AbstractIL.IL
+open FSharp.Compiler.AbstractIL.IL
open FSharp.Compiler.ErrorLogger
open FSharp.Compiler.Range
open System.Collections.Generic
@@ -83,10 +83,14 @@ type idd =
iddData: byte[];
iddChunk: BinaryChunk }
-val generatePortablePdb : embedAllSource:bool -> embedSourceList:string list -> sourceLink: string -> showTimes:bool -> info:PdbData -> isDeterministic:bool -> pathMap:PathMap -> (int64 * BlobContentId * MemoryStream)
+type HashAlgorithm =
+ | Sha1
+ | Sha256
+
+val generatePortablePdb : embedAllSource: bool -> embedSourceList: string list -> sourceLink: string -> checksumAlgorithm: HashAlgorithm -> showTimes: bool -> info: PdbData -> pathMap:PathMap -> (int64 * BlobContentId * MemoryStream * string * byte[])
val compressPortablePdbStream : uncompressedLength:int64 -> contentId:BlobContentId -> stream:MemoryStream -> (int64 * BlobContentId * MemoryStream)
-val embedPortablePdbInfo : uncompressedLength:int64 -> contentId:BlobContentId -> stream:MemoryStream -> showTimes:bool -> fpdb:string -> cvChunk:BinaryChunk -> pdbChunk:BinaryChunk -> idd[]
-val writePortablePdbInfo : contentId:BlobContentId -> stream:MemoryStream -> showTimes:bool -> fpdb:string -> pathMap:PathMap -> cvChunk:BinaryChunk -> idd[]
+val embedPortablePdbInfo: uncompressedLength: int64 -> contentId: BlobContentId -> stream: MemoryStream -> showTimes: bool -> fpdb: string -> cvChunk: BinaryChunk -> pdbChunk: BinaryChunk -> deterministicPdbChunk: BinaryChunk -> checksumPdbChunk: BinaryChunk -> algorithmName: string -> checksum: byte[] -> embeddedPDB: bool -> deterministic: bool -> idd[]
+val writePortablePdbInfo: contentId: BlobContentId -> stream: MemoryStream -> showTimes: bool -> fpdb: string -> pathMap: PathMap -> cvChunk: BinaryChunk -> deterministicPdbChunk: BinaryChunk -> checksumPdbChunk: BinaryChunk -> algorithmName: string -> checksum: byte[] -> embeddedPDB: bool -> deterministic: bool -> idd[]
#if !FX_NO_PDB_WRITER
val writePdbInfo : showTimes:bool -> f:string -> fpdb:string -> info:PdbData -> cvChunk:BinaryChunk -> idd[]
diff --git a/scripts/AssemblyVersionCheck.fsx b/src/buildtools/AssemblyCheck/AssemblyCheck.fs
similarity index 51%
rename from scripts/AssemblyVersionCheck.fsx
rename to src/buildtools/AssemblyCheck/AssemblyCheck.fs
index 0f3816a2e6..c6bd035a67 100644
--- a/scripts/AssemblyVersionCheck.fsx
+++ b/src/buildtools/AssemblyCheck/AssemblyCheck.fs
@@ -1,22 +1,50 @@
-// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information.
+// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information.
open System
open System.Diagnostics
open System.IO
open System.Reflection
+open System.Reflection.PortableExecutable
open System.Text.RegularExpressions
-module AssemblyVersionCheck =
+module AssemblyCheck =
let private versionZero = Version(0, 0, 0, 0)
let private versionOne = Version(1, 0, 0, 0)
let private commitHashPattern = new Regex(@"Commit Hash: ()|([0-9a-fA-F]{40})", RegexOptions.Compiled)
let private devVersionPattern = new Regex(@"-(ci|dev)", RegexOptions.Compiled)
- let verifyAssemblyVersions (binariesPath:string) =
+ let verifyEmbeddedPdb (filename:string) =
+ use fileStream = File.OpenRead(filename)
+ let reader = new PEReader(fileStream)
+ let mutable hasEmbeddedPdb = false
+
+ try
+ for entry in reader.ReadDebugDirectory() do
+ match entry.Type with
+ | DebugDirectoryEntryType.CodeView ->
+ let _ = reader.ReadCodeViewDebugDirectoryData(entry)
+ ()
+
+ | DebugDirectoryEntryType.EmbeddedPortablePdb ->
+ let _ = reader.ReadEmbeddedPortablePdbDebugDirectoryData(entry)
+ hasEmbeddedPdb <- true
+ ()
+
+ | DebugDirectoryEntryType.PdbChecksum ->
+ let _ = reader.ReadPdbChecksumDebugDirectoryData(entry)
+ ()
+
+ | _ -> ()
+ with | e -> printfn "Error validating assembly %s\nMessage: %s" filename (e.ToString())
+ hasEmbeddedPdb
+
+ let verifyAssemblies (binariesPath:string) =
+
let excludedAssemblies =
[ "FSharp.Data.TypeProviders.dll" ]
|> Set.ofList
+
let fsharpAssemblies =
[ "FSharp*.dll"
"fsc.exe"
@@ -28,12 +56,17 @@ module AssemblyVersionCheck =
|> List.ofSeq
|> List.filter (fun p -> (Set.contains (Path.GetFileName(p)) excludedAssemblies) |> not)
+ let fsharpExecutingWithEmbeddedPdbs =
+ fsharpAssemblies
+ |> List.filter (fun p -> not (p.Contains(@"\Proto\") || p.Contains(@"\Bootstrap\") || p.Contains(@".resources.") || p.Contains(@"\FSharpSdk\") || p.Contains(@"\tmp\") || p.Contains(@"\obj\")))
+
// verify that all assemblies have a version number other than 0.0.0.0 or 1.0.0.0
let failedVersionCheck =
fsharpAssemblies
|> List.filter (fun a ->
let assemblyVersion = AssemblyName.GetAssemblyName(a).Version
assemblyVersion = versionZero || assemblyVersion = versionOne)
+
if failedVersionCheck.Length > 0 then
printfn "The following assemblies had a version of %A or %A" versionZero versionOne
printfn "%s\r\n" <| String.Join("\r\n", failedVersionCheck)
@@ -43,27 +76,36 @@ module AssemblyVersionCheck =
// verify that all assemblies have a commit hash
let failedCommitHash =
fsharpAssemblies
+ |> List.filter (fun p -> not (p.Contains(@"\FSharpSdk\")))
|> List.filter (fun a ->
let fileProductVersion = FileVersionInfo.GetVersionInfo(a).ProductVersion
not (commitHashPattern.IsMatch(fileProductVersion) || devVersionPattern.IsMatch(fileProductVersion)))
+
if failedCommitHash.Length > 0 then
printfn "The following assemblies don't have a commit hash set"
printfn "%s\r\n" <| String.Join("\r\n", failedCommitHash)
else
printfn "All shipping assemblies had an appropriate commit hash."
+ // verify that all assemblies have an embedded pdb
+ let failedVerifyEmbeddedPdb =
+ fsharpExecutingWithEmbeddedPdbs
+ |> List.filter (fun a -> not (verifyEmbeddedPdb a))
+
+ if failedVerifyEmbeddedPdb.Length > 0 then
+ printfn "The following assemblies don't have an embedded pdb"
+ printfn "%s\r\n" <| String.Join("\r\n", failedVerifyEmbeddedPdb)
+ else
+ printfn "All shipping assemblies had an embedded PDB."
+
// return code is the number of failures
- failedVersionCheck.Length + failedCommitHash.Length
+ failedVersionCheck.Length + failedCommitHash.Length + failedVerifyEmbeddedPdb.Length
+
+[]
let main (argv:string array) =
if argv.Length <> 1 then
- printfn "Usage: fsi.exe AssemblyVersionCheck.fsx -- path/to/binaries"
+ printfn "Usage: dotnet AssemblyCheck.dll -- path/to/binaries"
1
else
- AssemblyVersionCheck.verifyAssemblyVersions argv.[0]
-
-Environment.GetCommandLineArgs()
-|> Seq.skipWhile ((<>) "--")
-|> Seq.skip 1
-|> Array.ofSeq
-|> main
+ AssemblyCheck.verifyAssemblies argv.[0]
diff --git a/src/buildtools/AssemblyCheck/AssemblyCheck.fsproj b/src/buildtools/AssemblyCheck/AssemblyCheck.fsproj
new file mode 100644
index 0000000000..72f79d02f9
--- /dev/null
+++ b/src/buildtools/AssemblyCheck/AssemblyCheck.fsproj
@@ -0,0 +1,17 @@
+
+
+
+ Exe
+ netcoreapp2.1
+ true
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/buildtools/buildtools.proj b/src/buildtools/buildtools.proj
index 593f086dd0..7ac48ba2a3 100644
--- a/src/buildtools/buildtools.proj
+++ b/src/buildtools/buildtools.proj
@@ -2,31 +2,33 @@
Debug
-
+ true
+
+
-
+
-
+
-
+
-
+
-
+
diff --git a/src/buildtools/buildtools.targets b/src/buildtools/buildtools.targets
index 303ab00825..185fd4d059 100644
--- a/src/buildtools/buildtools.targets
+++ b/src/buildtools/buildtools.targets
@@ -20,7 +20,7 @@
BeforeTargets="CoreCompile">
- $(ArtifactsDir)\Bootstrap\fslex.dll
+ $(ArtifactsDir)\Bootstrap\fslex\fslex.dll
@@ -43,7 +43,7 @@
BeforeTargets="CoreCompile">
- $(ArtifactsDir)\Bootstrap\fsyacc.dll
+ $(ArtifactsDir)\Bootstrap\fsyacc\fsyacc.dll
diff --git a/src/fsharp/CompileOps.fs b/src/fsharp/CompileOps.fs
index 85728909cf..5b75cf1077 100644
--- a/src/fsharp/CompileOps.fs
+++ b/src/fsharp/CompileOps.fs
@@ -17,6 +17,7 @@ open Internal.Utilities.Text
open FSharp.Compiler.AbstractIL
open FSharp.Compiler.AbstractIL.IL
open FSharp.Compiler.AbstractIL.ILBinaryReader
+open FSharp.Compiler.AbstractIL.ILPdbWriter
open FSharp.Compiler.AbstractIL.Internal
open FSharp.Compiler.AbstractIL.Internal.Library
open FSharp.Compiler.AbstractIL.Extensions.ILX
@@ -2100,6 +2101,7 @@ type TcConfigBuilder =
mutable maxErrors: int
mutable abortOnError: bool (* intended for fsi scripts that should exit on first error *)
mutable baseAddress: int32 option
+ mutable checksumAlgorithm: HashAlgorithm
#if DEBUG
mutable showOptimizationData: bool
#endif
@@ -2231,6 +2233,7 @@ type TcConfigBuilder =
maxErrors = 100
abortOnError = false
baseAddress = None
+ checksumAlgorithm = HashAlgorithm.Sha256
delaysign = false
publicsign = false
@@ -2740,6 +2743,7 @@ type TcConfig private (data: TcConfigBuilder, validate: bool) =
member x.flatErrors = data.flatErrors
member x.maxErrors = data.maxErrors
member x.baseAddress = data.baseAddress
+ member x.checksumAlgorithm = data.checksumAlgorithm
#if DEBUG
member x.showOptimizationData = data.showOptimizationData
#endif
diff --git a/src/fsharp/CompileOps.fsi b/src/fsharp/CompileOps.fsi
index 71bb7c6f8b..1262542cd9 100644
--- a/src/fsharp/CompileOps.fsi
+++ b/src/fsharp/CompileOps.fsi
@@ -10,6 +10,7 @@ open Internal.Utilities
open FSharp.Compiler.AbstractIL
open FSharp.Compiler.AbstractIL.IL
open FSharp.Compiler.AbstractIL.ILBinaryReader
+open FSharp.Compiler.AbstractIL.ILPdbWriter
open FSharp.Compiler.AbstractIL.Internal.Library
open FSharp.Compiler
open FSharp.Compiler.TypeChecker
@@ -337,6 +338,7 @@ type TcConfigBuilder =
mutable maxErrors: int
mutable abortOnError: bool
mutable baseAddress: int32 option
+ mutable checksumAlgorithm: HashAlgorithm
#if DEBUG
mutable showOptimizationData: bool
#endif
@@ -497,6 +499,7 @@ type TcConfig =
member maxErrors: int
member baseAddress: int32 option
+ member checksumAlgorithm: HashAlgorithm
#if DEBUG
member showOptimizationData: bool
#endif
diff --git a/src/fsharp/CompileOptions.fs b/src/fsharp/CompileOptions.fs
index 0c385cc367..e548a49e71 100755
--- a/src/fsharp/CompileOptions.fs
+++ b/src/fsharp/CompileOptions.fs
@@ -9,6 +9,7 @@ open System
open FSharp.Compiler
open FSharp.Compiler.AbstractIL
open FSharp.Compiler.AbstractIL.IL
+open FSharp.Compiler.AbstractIL.ILPdbWriter
open FSharp.Compiler.AbstractIL.Internal.Library
open FSharp.Compiler.AbstractIL.Extensions.ILX
open FSharp.Compiler.AbstractIL.Diagnostics
@@ -522,6 +523,7 @@ let tagFullPDBOnlyPortable = "{full|pdbonly|portable|embedded}"
let tagWarnList = ""
let tagSymbolList = ""
let tagAddress = ""
+let tagAlgorithm = "{SHA1|SHA256}"
let tagInt = ""
let tagPathMap = ""
let tagNone = ""
@@ -933,6 +935,16 @@ let advancedFlagsFsc tcConfigB =
OptionString (fun s -> tcConfigB.baseAddress <- Some(int32 s)), None,
Some (FSComp.SR.optsBaseaddress()))
+ yield CompilerOption
+ ("checksumalgorithm", tagAlgorithm,
+ OptionString (fun s ->
+ tcConfigB.checksumAlgorithm <-
+ match s.ToUpperInvariant() with
+ | "SHA1" -> HashAlgorithm.Sha1
+ | "SHA256" -> HashAlgorithm.Sha256
+ | _ -> error(Error(FSComp.SR.optsUnknownChecksumAlgorithm s, rangeCmdArgs))), None,
+ Some (FSComp.SR.optsChecksumAlgorithm()))
+
yield noFrameworkFlag true tcConfigB
yield CompilerOption
diff --git a/src/fsharp/ConstraintSolver.fs b/src/fsharp/ConstraintSolver.fs
index 94c28b76e5..1cb860abae 100755
--- a/src/fsharp/ConstraintSolver.fs
+++ b/src/fsharp/ConstraintSolver.fs
@@ -64,10 +64,10 @@ let compgenId = mkSynId range0 unassignedTyparName
let NewCompGenTypar (kind, rigid, staticReq, dynamicReq, error) =
NewTypar(kind, rigid, Typar(compgenId, staticReq, true), error, dynamicReq, [], false, false)
-let anon_id m = mkSynId m unassignedTyparName
+let AnonTyparId m = mkSynId m unassignedTyparName
let NewAnonTypar (kind, m, rigid, var, dyn) =
- NewTypar (kind, rigid, Typar(anon_id m, var, true), false, dyn, [], false, false)
+ NewTypar (kind, rigid, Typar(AnonTyparId m, var, true), false, dyn, [], false, false)
let NewNamedInferenceMeasureVar (_m, rigid, var, id) =
NewTypar(TyparKind.Measure, rigid, Typar(id, var, false), false, TyparDynamicReq.No, [], false, false)
@@ -104,6 +104,7 @@ let FreshenAndFixupTypars m rigid fctps tinst tpsorig =
tps, renaming, tinst
let FreshenTypeInst m tpsorig = FreshenAndFixupTypars m TyparRigidity.Flexible [] [] tpsorig
+
let FreshMethInst m fctps tinst tpsorig = FreshenAndFixupTypars m TyparRigidity.Flexible fctps tinst tpsorig
let FreshenTypars m tpsorig =
@@ -126,62 +127,95 @@ let FreshenMethInfo m (minfo: MethInfo) =
[]
/// Information about the context of a type equation.
type ContextInfo =
+
/// No context was given.
| NoContext
+
/// The type equation comes from an IF expression.
| IfExpression of range
+
/// The type equation comes from an omitted else branch.
| OmittedElseBranch of range
+
/// The type equation comes from a type check of the result of an else branch.
| ElseBranchResult of range
+
/// The type equation comes from the verification of record fields.
| RecordFields
+
/// The type equation comes from the verification of a tuple in record fields.
| TupleInRecordFields
+
/// The type equation comes from a list or array constructor
| CollectionElement of bool * range
+
/// The type equation comes from a return in a computation expression.
+
| ReturnInComputationExpression
+
/// The type equation comes from a yield in a computation expression.
| YieldInComputationExpression
+
/// The type equation comes from a runtime type test.
| RuntimeTypeTest of bool
+
/// The type equation comes from an downcast where a upcast could be used.
| DowncastUsedInsteadOfUpcast of bool
+
/// The type equation comes from a return type of a pattern match clause (not the first clause).
| FollowingPatternMatchClause of range
+
/// The type equation comes from a pattern match guard.
| PatternMatchGuard of range
+
/// The type equation comes from a sequence expression.
| SequenceExpression of TType
-exception ConstraintSolverTupleDiffLengths of displayEnv: DisplayEnv * TType list * TType list * range * range
-exception ConstraintSolverInfiniteTypes of displayEnv: DisplayEnv * contextInfo: ContextInfo * TType * TType * range * range
-exception ConstraintSolverTypesNotInEqualityRelation of displayEnv: DisplayEnv * TType * TType * range * range * ContextInfo
+exception ConstraintSolverTupleDiffLengths of displayEnv: DisplayEnv * TType list * TType list * range * range
+
+exception ConstraintSolverInfiniteTypes of displayEnv: DisplayEnv * contextInfo: ContextInfo * TType * TType * range * range
+
+exception ConstraintSolverTypesNotInEqualityRelation of displayEnv: DisplayEnv * TType * TType * range * range * ContextInfo
+
exception ConstraintSolverTypesNotInSubsumptionRelation of displayEnv: DisplayEnv * TType * TType * range * range
-exception ConstraintSolverMissingConstraint of displayEnv: DisplayEnv * Tast.Typar * Tast.TyparConstraint * range * range
-exception ConstraintSolverError of string * range * range
-exception ConstraintSolverRelatedInformation of string option * range * exn
-exception ErrorFromApplyingDefault of tcGlobals: TcGlobals * displayEnv: DisplayEnv * Tast.Typar * TType * exn * range
-exception ErrorFromAddingTypeEquation of tcGlobals: TcGlobals * displayEnv: DisplayEnv * TType * TType * exn * range
+exception ConstraintSolverMissingConstraint of displayEnv: DisplayEnv * Tast.Typar * Tast.TyparConstraint * range * range
+
+exception ConstraintSolverError of string * range * range
+
+exception ConstraintSolverRelatedInformation of string option * range * exn
+
+exception ErrorFromApplyingDefault of tcGlobals: TcGlobals * displayEnv: DisplayEnv * Tast.Typar * TType * exn * range
+
+exception ErrorFromAddingTypeEquation of tcGlobals: TcGlobals * displayEnv: DisplayEnv * TType * TType * exn * range
+
exception ErrorsFromAddingSubsumptionConstraint of tcGlobals: TcGlobals * displayEnv: DisplayEnv * TType * TType * exn * ContextInfo * range
-exception ErrorFromAddingConstraint of displayEnv: DisplayEnv * exn * range
-exception PossibleOverload of displayEnv: DisplayEnv * string * exn * range
-exception UnresolvedOverloading of displayEnv: DisplayEnv * exn list * string * range
-exception UnresolvedConversionOperator of displayEnv: DisplayEnv * TType * TType * range
+
+exception ErrorFromAddingConstraint of displayEnv: DisplayEnv * exn * range
+
+exception PossibleOverload of displayEnv: DisplayEnv * string * exn * range
+
+exception UnresolvedOverloading of displayEnv: DisplayEnv * exn list * string * range
+
+exception UnresolvedConversionOperator of displayEnv: DisplayEnv * TType * TType * range
let GetPossibleOverloads amap m denv (calledMethGroup: (CalledMeth<_> * exn) list) =
- calledMethGroup |> List.map (fun (cmeth, e) -> PossibleOverload(denv, NicePrint.stringOfMethInfo amap m denv cmeth.Method, e, m))
+ calledMethGroup |> List.map (fun (cmeth, e) ->
+ PossibleOverload(denv, NicePrint.stringOfMethInfo amap m denv cmeth.Method, e, m))
type TcValF = (ValRef -> ValUseFlag -> TType list -> range -> Expr * TType)
type ConstraintSolverState =
{
g: TcGlobals
+
amap: Import.ImportMap
+
InfoReader: InfoReader
+
+ /// The function used to freshen values we encounter during trait constraint solving
TcVal: TcValF
+
/// This table stores all unsolved, ungeneralized trait constraints, indexed by free type variable.
/// That is, there will be one entry in this table for each free type variable in
/// each outstanding, unsolved, ungeneralized trait constraint. Constraints are removed from the table and resolved
@@ -196,20 +230,29 @@ type ConstraintSolverState =
InfoReader = infoReader
TcVal = tcVal }
-
type ConstraintSolverEnv =
{
SolverState: ConstraintSolverState
+
eContextInfo: ContextInfo
+
MatchingOnly: bool
+
m: range
+
EquivEnv: TypeEquivEnv
+
DisplayEnv: DisplayEnv
}
+
member csenv.InfoReader = csenv.SolverState.InfoReader
+
member csenv.g = csenv.SolverState.g
+
member csenv.amap = csenv.SolverState.amap
+ override csenv.ToString() = " @ " + csenv.m.ToString()
+
let MakeConstraintSolverEnv contextInfo css m denv =
{ SolverState = css
m = m
@@ -219,11 +262,6 @@ let MakeConstraintSolverEnv contextInfo css m denv =
EquivEnv = TypeEquivEnv.Empty
DisplayEnv = denv }
-
-//-------------------------------------------------------------------------
-// Occurs check
-//-------------------------------------------------------------------------
-
/// Check whether a type variable occurs in the r.h.s. of a type, e.g. to catch
/// infinite equations such as
/// 'a = list<'a>
@@ -287,9 +325,13 @@ let isDecimalTy g ty =
typeEquivAux EraseMeasures g g.decimal_ty ty
let IsNonDecimalNumericOrIntegralEnumType g ty = isIntegerOrIntegerEnumTy g ty || isFpTy g ty
+
let IsNumericOrIntegralEnumType g ty = IsNonDecimalNumericOrIntegralEnumType g ty || isDecimalTy g ty
+
let IsNonDecimalNumericType g ty = isIntegerTy g ty || isFpTy g ty
+
let IsNumericType g ty = IsNonDecimalNumericType g ty || isDecimalTy g ty
+
let IsRelationalType g ty = IsNumericType g ty || isStringTy g ty || isCharTy g ty || isBoolTy g ty
// Get measure of type, float<_> or float32<_> or decimal<_> but not float=float<1> or float32=float32<1> or decimal=decimal<1>
@@ -386,8 +428,11 @@ let ShowAccessDomain ad =
// Solve
exception NonRigidTypar of displayEnv: DisplayEnv * string option * range * TType * TType * range
+
exception LocallyAbortOperationThatFailsToResolveOverload
+
exception LocallyAbortOperationThatLosesAbbrevs
+
let localAbortD = ErrorD LocallyAbortOperationThatLosesAbbrevs
/// Return true if we would rather unify this variable v1 := v2 than vice versa
@@ -652,7 +697,6 @@ let NormalizeExponentsInTypeScheme uvars ty =
SubstMeasure v (Measure.RationalPower (Measure.Var v', DivRational OneRational expGcd))
v')
-
// We normalize unit-of-measure-polymorphic type schemes. There
// are three reasons for doing this:
// (1) to present concise and consistent type schemes to the programmer
@@ -732,8 +776,6 @@ let rec SolveTyparEqualsType (csenv: ConstraintSolverEnv) ndeep m2 (trace: Optio
// Record a entry in the undo trace if one is provided
trace.Exec (fun () -> r.typar_solution <- Some ty) (fun () -> r.typar_solution <- None)
- (* dprintf "setting typar %d to type %s at %a\n" r.Stamp ((DebugPrint.showType ty)) outputRange m; *)
-
// Only solve constraints if this is not an error var
if r.IsFromError then () else
// Check to see if this type variable is relevant to any trait constraints.
@@ -745,15 +787,17 @@ let rec SolveTyparEqualsType (csenv: ConstraintSolverEnv) ndeep m2 (trace: Optio
| _ -> failwith "SolveTyparEqualsType"
}
-
/// Apply the constraints on 'typar' to the type 'ty'
and solveTypMeetsTyparConstraints (csenv: ConstraintSolverEnv) ndeep m2 trace ty (r: Typar) = trackErrors {
let g = csenv.g
+
// Propagate compat flex requirements from 'tp' to 'ty'
do! SolveTypIsCompatFlex csenv trace r.IsCompatFlex ty
+
// Propagate dynamic requirements from 'tp' to 'ty'
do! SolveTypDynamicReq csenv trace r.DynamicReq ty
+
// Propagate static requirements from 'tp' to 'ty'
do! SolveTypStaticReq csenv trace r.StaticReq ty
@@ -899,6 +943,7 @@ and SolveTypeSubsumesType (csenv: ConstraintSolverEnv) ndeep m2 (trace: Optional
let amap = csenv.amap
let aenv = csenv.EquivEnv
let denv = csenv.DisplayEnv
+
match sty1, sty2 with
| TType_var tp1, _ ->
match aenv.EquivTypars.TryFind tp1 with
@@ -914,15 +959,19 @@ and SolveTypeSubsumesType (csenv: ConstraintSolverEnv) ndeep m2 (trace: Optional
| TType_tuple (tupInfo1, l1), TType_tuple (tupInfo2, l2) ->
if evalTupInfoIsStruct tupInfo1 <> evalTupInfoIsStruct tupInfo2 then ErrorD (ConstraintSolverError(FSComp.SR.tcTupleStructMismatch(), csenv.m, m2)) else
SolveTypeEqualsTypeEqns csenv ndeep m2 trace cxsln l1 l2 (* nb. can unify since no variance *)
+
| TType_anon (anonInfo1, l1), TType_anon (anonInfo2, l2) ->
SolveAnonInfoEqualsAnonInfo csenv m2 anonInfo1 anonInfo2 ++ (fun () ->
SolveTypeEqualsTypeEqns csenv ndeep m2 trace cxsln l1 l2) (* nb. can unify since no variance *)
+
| TType_fun (d1, r1), TType_fun (d2, r2) -> SolveFunTypeEqn csenv ndeep m2 trace cxsln d1 d2 r1 r2 (* nb. can unify since no variance *)
+
| TType_measure ms1, TType_measure ms2 -> UnifyMeasures csenv trace ms1 ms2
// Enforce the identities float=float<1>, float32=float32<1> and decimal=decimal<1>
| (_, TType_app (tc2, [ms])) when (tc2.IsMeasureableReprTycon && typeEquiv csenv.g sty1 (reduceTyconRefMeasureableOrProvided csenv.g tc2 [ms]))
-> SolveTypeEqualsTypeKeepAbbrevsWithCxsln csenv ndeep m2 trace cxsln ms (TType_measure Measure.One)
+
| (TType_app (tc2, [ms]), _) when (tc2.IsMeasureableReprTycon && typeEquiv csenv.g sty2 (reduceTyconRefMeasureableOrProvided csenv.g tc2 [ms]))
-> SolveTypeEqualsTypeKeepAbbrevsWithCxsln csenv ndeep m2 trace cxsln ms (TType_measure Measure.One)
@@ -973,6 +1022,7 @@ and SolveTypeSubsumesType (csenv: ConstraintSolverEnv) ndeep m2 (trace: Optional
let ty2arg = destArrayTy g ty2
SolveTypeEqualsTypeKeepAbbrevsWithCxsln csenv ndeep m2 trace cxsln ty1arg ty2arg
| _ -> error(InternalError("destArrayTy", m))
+
| _ ->
// D :> Head<_> --> C :> Head<_> for the
// first interface or super-class C supported by D which
@@ -991,7 +1041,6 @@ and SolveTypeSubsumesTypeKeepAbbrevs csenv ndeep m2 trace cxsln ty1 ty2 =
// Solve and record non-equality constraints
//-------------------------------------------------------------------------
-
and SolveTyparSubtypeOfType (csenv: ConstraintSolverEnv) ndeep m2 trace tp ty1 =
let g = csenv.g
if isObjTy g ty1 then CompleteD
@@ -1052,7 +1101,7 @@ and SolveMemberConstraint (csenv: ConstraintSolverEnv) ignoreUnresolvedOverload
| _ -> do! ErrorD (ConstraintSolverError(FSComp.SR.csExpectedArguments(), m, m2))
// Trait calls are only supported on pseudo type (variables)
for e in tys do
- do! SolveTypStaticReq csenv trace HeadTypeStaticReq e
+ do! SolveTypStaticReq csenv trace HeadTypeStaticReq e
let argtys = if memFlags.IsInstance then List.tail argtys else argtys
@@ -1108,14 +1157,18 @@ and SolveMemberConstraint (csenv: ConstraintSolverEnv) ignoreUnresolvedOverload
do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace argty2 (mkAppTy tcref [TType_measure ms2])
do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace rty (mkAppTy tcref [TType_measure (Measure.Prod(ms1, if nm = "op_Multiply" then ms2 else Measure.Inv ms2))])
return TTraitBuiltIn
+
| _ ->
+
match GetMeasureOfType g argty2 with
| Some (tcref, ms2) ->
let ms1 = freshMeasure ()
do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace argty1 (mkAppTy tcref [TType_measure ms1])
do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace rty (mkAppTy tcref [TType_measure (Measure.Prod(ms1, if nm = "op_Multiply" then ms2 else Measure.Inv ms2))])
return TTraitBuiltIn
+
| _ ->
+
do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace argty2 argty1
do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace rty argty1
return TTraitBuiltIn
@@ -1931,7 +1984,7 @@ and SolveTypeIsNonNullableValueType (csenv: ConstraintSolverEnv) ndeep m2 trace
| _ ->
let underlyingTy = stripTyEqnsAndMeasureEqns g ty
if isStructTy g underlyingTy then
- if isAppTy g underlyingTy && tyconRefEq g g.system_Nullable_tcref (tcrefOfAppTy g underlyingTy) then
+ if isNullableTy g underlyingTy then
return! ErrorD (ConstraintSolverError(FSComp.SR.csTypeParameterCannotBeNullable(), m, m))
else
return! ErrorD (ConstraintSolverError(FSComp.SR.csGenericConstructRequiresStructType(NicePrint.minimalStringOfType denv ty), m, m2))
diff --git a/src/fsharp/DetupleArgs.fs b/src/fsharp/DetupleArgs.fs
index 8ae41acb31..b15bae8f24 100755
--- a/src/fsharp/DetupleArgs.fs
+++ b/src/fsharp/DetupleArgs.fs
@@ -644,17 +644,26 @@ let hasTransfrom penv f = Zmap.tryFind f penv.transforms
*)
type env =
- { eg : TcGlobals
- prefix : string
- m : Range.range }
+ {
+ eg: TcGlobals
+
+ prefix: string
+
+ m: Range.range
+ }
+
+ override __.ToString() = ""
let suffixE env s = {env with prefix = env.prefix + s}
+
let rangeE env m = {env with m = m}
let push b bs = b :: bs
+
let pushL xs bs = xs@bs
let newLocal env ty = mkCompGenLocal env.m env.prefix ty
+
let newLocalN env i ty = mkCompGenLocal env.m (env.prefix + string i) ty
let noEffectExpr env bindings x =
@@ -712,7 +721,6 @@ and collapseArgs env bindings n (callPattern) args =
| _ts :: _tss, [] ->
internalError "collapseArgs: CallPattern longer than callsite args. REPORT BUG"
-
//-------------------------------------------------------------------------
// pass - app fixup
//-------------------------------------------------------------------------
diff --git a/src/fsharp/FSComp.txt b/src/fsharp/FSComp.txt
index ee2b41f2e9..831597c031 100755
--- a/src/fsharp/FSComp.txt
+++ b/src/fsharp/FSComp.txt
@@ -878,6 +878,7 @@ optsUtf8output,"Output messages in UTF-8 encoding"
optsFullpaths,"Output messages with fully qualified paths"
optsLib,"Specify a directory for the include path which is used to resolve source files and assemblies (Short form: -I)"
optsBaseaddress,"Base address for the library to be built"
+optsChecksumAlgorithm,"Specify algorithm for calculating source file checksum stored in PDB. Supported values are: SHA1 or SHA256 (default)"
optsNoframework,"Do not reference the default CLI assemblies by default"
optsStandalone,"Statically link the F# library and all referenced DLLs that depend on it into the assembly being generated"
optsStaticlink,"Statically link the given assembly and all referenced DLLs that depend on this assembly. Use an assembly name e.g. mylib, not a DLL name."
@@ -900,6 +901,7 @@ optsHelpBannerLanguage,"- LANGUAGE -"
optsHelpBannerErrsAndWarns,"- ERRORS AND WARNINGS -"
1063,optsUnknownArgumentToTheTestSwitch,"Unknown --test argument: '%s'"
1064,optsUnknownPlatform,"Unrecognized platform '%s', valid values are 'x86', 'x64', 'Itanium', 'anycpu32bitpreferred', and 'anycpu'"
+1065,optsUnknownChecksumAlgorithm,"Algorithm '%s' is not supported"
optsInternalNoDescription,"The command-line option '%s' is for test purposes only"
optsDCLONoDescription,"The command-line option '%s' has been deprecated"
optsDCLODeprecatedSuggestAlternative,"The command-line option '%s' has been deprecated. Use '%s' instead."
diff --git a/src/fsharp/FSharp.Compiler.Interactive.Settings/Directory.Build.props b/src/fsharp/FSharp.Compiler.LanguageServer/Directory.Build.props
similarity index 100%
rename from src/fsharp/FSharp.Compiler.Interactive.Settings/Directory.Build.props
rename to src/fsharp/FSharp.Compiler.LanguageServer/Directory.Build.props
diff --git a/src/fsharp/FSharp.Compiler.LanguageServer/FSharp.Compiler.LanguageServer.fsproj b/src/fsharp/FSharp.Compiler.LanguageServer/FSharp.Compiler.LanguageServer.fsproj
new file mode 100644
index 0000000000..fd6e517e54
--- /dev/null
+++ b/src/fsharp/FSharp.Compiler.LanguageServer/FSharp.Compiler.LanguageServer.fsproj
@@ -0,0 +1,50 @@
+
+
+
+
+ Exe
+ .exe
+ net472;netcoreapp3.0
+ netcoreapp3.0
+ true
+ Implements the Language Server Protocol (LSP) for F#.
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <_PublishedProjectOutputGroupFiles Include="$(PublishDir)\**" />
+
+
+
+
+
+
+
+
+
+
diff --git a/src/fsharp/FSharp.Compiler.LanguageServer/JsonDUConverter.fs b/src/fsharp/FSharp.Compiler.LanguageServer/JsonDUConverter.fs
new file mode 100644
index 0000000000..ae8575195d
--- /dev/null
+++ b/src/fsharp/FSharp.Compiler.LanguageServer/JsonDUConverter.fs
@@ -0,0 +1,18 @@
+// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information.
+
+namespace FSharp.Compiler.LanguageServer
+
+open System
+open FSharp.Reflection
+open Newtonsoft.Json
+
+type JsonDUConverter() =
+ inherit JsonConverter()
+ override __.CanConvert(typ) = FSharpType.IsUnion(typ)
+ override __.WriteJson(writer, value, _serializer) =
+ writer.WriteValue(value.ToString().ToLowerInvariant())
+ override __.ReadJson(reader, typ, x, serializer) =
+ let cases = FSharpType.GetUnionCases(typ)
+ let str = serializer.Deserialize(reader, typeof) :?> string
+ let case = cases |> Array.find (fun c -> String.Compare(c.Name, str, StringComparison.OrdinalIgnoreCase) = 0)
+ FSharpValue.MakeUnion(case, [||])
diff --git a/src/fsharp/FSharp.Compiler.LanguageServer/JsonOptionConverter.fs b/src/fsharp/FSharp.Compiler.LanguageServer/JsonOptionConverter.fs
new file mode 100644
index 0000000000..937dda00e4
--- /dev/null
+++ b/src/fsharp/FSharp.Compiler.LanguageServer/JsonOptionConverter.fs
@@ -0,0 +1,27 @@
+// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information.
+
+namespace FSharp.Compiler.LanguageServer
+
+open System
+open FSharp.Reflection
+open Newtonsoft.Json
+
+type JsonOptionConverter() =
+ inherit JsonConverter()
+ override __.CanConvert(typ) = typ.IsGenericType && typ.GetGenericTypeDefinition() = typedefof