Ver Fonte

Merge branch 'release/3.1' into 'master'

Doug Bunting há 6 anos atrás
pai
commit
339c720d86
100 ficheiros alterados com 2027 adições e 1400 exclusões
  1. 602 499
      .azure/pipelines/ci.yml
  2. 24 6
      .azure/pipelines/jobs/codesign-xplat.yml
  3. 168 190
      .azure/pipelines/jobs/default-build.yml
  4. 10 1
      Directory.Build.props
  5. 2 9
      Directory.Build.targets
  6. 5 1
      build.sh
  7. 2 1
      dockerbuild.sh
  8. 24 10
      docs/Artifacts.md
  9. 0 11
      eng/AfterSolutionBuild.targets
  10. 1 0
      eng/Build.props
  11. 1 1
      eng/CodeGen.proj
  12. 2 0
      eng/Dependencies.props
  13. 2 0
      eng/PatchConfig.props
  14. 2 0
      eng/ProjectReferences.props
  15. 56 0
      eng/Publishing.props
  16. 4 0
      eng/SignCheckExclusionsFile.txt
  17. 1 0
      eng/Signing.props
  18. 6 6
      eng/Version.Details.xml
  19. 16 9
      eng/Versions.props
  20. 5 0
      eng/Workarounds.props
  21. 15 0
      eng/Workarounds.targets
  22. 4 0
      eng/common/build.ps1
  23. 4 4
      eng/common/performance/perfhelixpublish.proj
  24. 1 1
      eng/common/performance/performance-setup.ps1
  25. 1 1
      eng/common/performance/performance-setup.sh
  26. 9 8
      eng/common/sdl/execute-all-sdl-tools.ps1
  27. 5 5
      eng/common/sdl/run-sdl.ps1
  28. 4 1
      eng/common/templates/job/job.yml
  29. 5 3
      eng/common/templates/job/performance.yml
  30. 7 0
      eng/common/templates/job/publish-build-assets.yml
  31. 26 65
      eng/common/templates/post-build/channels/netcore-dev-30.yml
  32. 126 0
      eng/common/templates/post-build/channels/netcore-dev-31.yml
  33. 34 73
      eng/common/templates/post-build/channels/netcore-dev-5.yml
  34. 37 71
      eng/common/templates/post-build/channels/netcore-internal-30.yml
  35. 39 72
      eng/common/templates/post-build/channels/netcore-release-30.yml
  36. 126 0
      eng/common/templates/post-build/channels/netcore-release-31.yml
  37. 34 73
      eng/common/templates/post-build/channels/netcore-tools-latest.yml
  38. 32 50
      eng/common/templates/post-build/channels/public-validation-release.yml
  39. 26 6
      eng/common/templates/post-build/common-variables.yml
  40. 16 6
      eng/common/templates/post-build/post-build.yml
  41. 13 0
      eng/common/templates/steps/promote-build.yml
  42. 17 1
      eng/common/tools.ps1
  43. 16 0
      eng/common/tools.sh
  44. 2 1
      eng/docker/alpine.Dockerfile
  45. 2 1
      eng/docker/bionic.Dockerfile
  46. 2 1
      eng/docker/rhel.Dockerfile
  47. 2 1
      eng/docker/ubuntu-alpine37.Dockerfile
  48. 5 0
      eng/empty.proj
  49. 76 0
      eng/scripts/FinishDumpCollectionForHangingBuilds.ps1
  50. 46 0
      eng/scripts/InstallProcDump.ps1
  51. 123 0
      eng/scripts/StartDumpCollectionForHangingBuilds.ps1
  52. 1 1
      eng/scripts/ci-source-build.sh
  53. 0 38
      eng/tools/Maestro/Maestro.csproj
  54. 0 38
      eng/tools/XplatPackageSigner/XplatPackageSigner.proj
  55. 0 15
      eng/tools/XplatPackageSigner/sign-packages.cmd
  56. 2 2
      global.json
  57. 5 0
      src/Analyzers/shared/FeatureDetection/Microsoft.AspNetCore.Analyzers.FeatureDetection.Sources.csproj
  58. 0 0
      src/Analyzers/shared/FeatureDetection/lib/netstandard1.0/_._
  59. 1 0
      src/Antiforgery/src/Microsoft.AspNetCore.Antiforgery.csproj
  60. 2 1
      src/Components/Authorization/src/CascadingAuthenticationState.razor
  61. 0 9
      src/Components/Blazor/Directory.Build.props
  62. 0 2
      src/Components/Blazor/Templates/src/content/BlazorWasm-CSharp/Client/BlazorWasm-CSharp.Client.csproj
  63. 2 2
      src/Components/Blazor/Templates/src/content/BlazorWasm-CSharp/Client/Pages/Counter.razor
  64. 2 2
      src/Components/Blazor/Templates/src/content/BlazorWasm-CSharp/Client/Pages/FetchData.razor
  65. 3 3
      src/Components/Blazor/Templates/src/content/BlazorWasm-CSharp/Client/Shared/NavMenu.razor
  66. 2 1
      src/Components/Blazor/Templates/src/content/BlazorWasm-CSharp/Client/Shared/SurveyPrompt.razor
  67. 0 1
      src/Components/Blazor/Templates/src/content/BlazorWasm-CSharp/Server/BlazorWasm-CSharp.Server.csproj
  68. 1 2
      src/Components/Blazor/Templates/src/content/BlazorWasm-CSharp/Server/Startup.cs
  69. 2 1
      src/Components/Blazor/testassets/HostedInAspNet.Server/HostedInAspNet.Server.csproj
  70. 9 10
      src/Components/Blazor/testassets/HostedInAspNet.Server/Program.cs
  71. 2 1
      src/Components/Blazor/testassets/MonoSanity/MonoSanity.csproj
  72. 9 10
      src/Components/Blazor/testassets/MonoSanity/Program.cs
  73. 36 34
      src/Components/Components.sln
  74. 3 4
      src/Components/Components/src/Microsoft.AspNetCore.Components.csproj
  75. 3 3
      src/Components/Components/src/Microsoft.AspNetCore.Components.multitarget.nuspec
  76. 3 3
      src/Components/Components/src/Microsoft.AspNetCore.Components.netcoreapp.nuspec
  77. 0 2
      src/Components/Components/src/Properties/AssemblyInfo.cs
  78. 4 0
      src/Components/Components/src/RenderTree/ArrayBuilderExtensions.cs
  79. 4 0
      src/Components/Components/src/RenderTree/ArrayBuilderSegment.cs
  80. 4 0
      src/Components/Components/src/RenderTree/ArrayRange.cs
  81. 4 0
      src/Components/Components/src/RenderTree/RenderBatch.cs
  82. 4 0
      src/Components/Components/src/RenderTree/RenderTreeDiff.cs
  83. 4 0
      src/Components/Components/src/RenderTree/RenderTreeEdit.cs
  84. 4 0
      src/Components/Components/src/RenderTree/RenderTreeEditType.cs
  85. 6 0
      src/Components/Components/src/RenderTree/RenderTreeFrame.cs
  86. 4 0
      src/Components/Components/src/RenderTree/RenderTreeFrameType.cs
  87. 9 10
      src/Components/ComponentsNoDeps.slnf
  88. 26 5
      src/Components/Ignitor/src/BlazorClient.cs
  89. 17 0
      src/Components/Ignitor/src/CapturedAttachComponentCall.cs
  90. 0 0
      src/Components/Ignitor/src/CapturedJSInteropCall.cs
  91. 0 0
      src/Components/Ignitor/src/CapturedRenderBatch.cs
  92. 0 0
      src/Components/Ignitor/src/CommentNode.cs
  93. 0 0
      src/Components/Ignitor/src/ComponentNode.cs
  94. 16 0
      src/Components/Ignitor/src/ComponentState.cs
  95. 1 1
      src/Components/Ignitor/src/ContainerNode.cs
  96. 0 2
      src/Components/Ignitor/src/ElementHive.cs
  97. 5 9
      src/Components/Ignitor/src/ElementNode.cs
  98. 29 0
      src/Components/Ignitor/src/ElementReference.cs
  99. 0 0
      src/Components/Ignitor/src/Error.cs
  100. 10 0
      src/Components/Ignitor/src/IComponent.cs

+ 602 - 499
.azure/pipelines/ci.yml

@@ -22,526 +22,629 @@ variables:
   value: true
 - name: _TeamName
   value:  AspNetCore
-- ${{ if and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}:
-  - name: _BuildArgs
-    value: /p:TeamName=$(_TeamName)
-      /p:OfficialBuildId=$(Build.BuildNumber)
-- ${{ if or(eq(variables['System.TeamProject'], 'public'), in(variables['Build.Reason'], 'PullRequest')) }}:
+- name: _DotNetPublishToBlobFeed
+  value: true
+- name: _PublishUsingPipelines
+  value: true
+- name: _DotNetArtifactsCategory
+  value: .NETCORE
+- name: _DotNetValidationArtifactsCategory
+  value: .NETCORE
+- ${{ if ne(variables['System.TeamProject'], 'internal') }}:
   - name: _BuildArgs
     value: ''
+  - name: _PublishArgs
+    value: ''
+  - name: _SignType
+    value: ''
+- ${{ if eq(variables['System.TeamProject'], 'internal') }}:
+  - ${{ if ne(variables['Build.Reason'], 'PullRequest') }}:
+    # DotNet-Blob-Feed provides: dotnetfeed-storage-access-key-1
+    # Publish-Build-Assets provides: MaestroAccessToken, BotAccount-dotnet-maestro-bot-PAT
+    - group: DotNet-Blob-Feed
+    - group: Publish-Build-Assets
 
-jobs:
-# Code check
-- template: jobs/default-build.yml
-  parameters:
-    jobName: Code_check
-    jobDisplayName: Code check
-    agentOs: Windows
-    steps:
-    - powershell: ./eng/scripts/CodeCheck.ps1 -ci
-      displayName: Run eng/scripts/CodeCheck.ps1
-    artifacts:
-    - name: Code_Check_Logs
-      path: artifacts/log/
-      publishOnError: true
+    - name: _BuildArgs
+      value: /p:TeamName=$(_TeamName)
+             /p:OfficialBuildId=$(Build.BuildNumber)
+    - name: _SignType
+      value: real
 
-# Build Windows (x64/x86)
-- template: jobs/default-build.yml
-  parameters:
-    codeSign: true
-    jobName: Windows_build
-    jobDisplayName: "Build: Windows x64/x86"
-    agentOs: Windows
-    steps:
-    - script: "echo ##vso[build.addbuildtag]daily-build"
-      condition: and(ne(variables['Build.Reason'], 'PullRequest'), notin(variables['DotNetFinalVersionKind'], 'release', 'prerelease'))
-      displayName: 'Set CI tags'
-    - script: "echo ##vso[build.addbuildtag]release-candidate"
-      condition: and(ne(variables['Build.Reason'], 'PullRequest'), in(variables['DotNetFinalVersionKind'], 'release', 'prerelease'))
-      displayName: 'Set CI tags'
-    # !!! NOTE !!! Some of these steps have disabled code signing.
-    # This is intentional to workaround https://github.com/dotnet/arcade/issues/1957 which always re-submits for code-signing, even
-    # if they have already been signed. This results in slower builds due to re-submitting the same .nupkg many times for signing.
-    # The sign settings have been configured to
+    # The following extra properties are not set when testing. Use with final build.[cmd,sh] of asset-producing jobs.
+    - name: _PublishArgs
+      value: /p:Publish=true
+             /p:DotNetPublishBlobFeedKey=$(dotnetfeed-storage-access-key-1)
+             /p:DotNetPublishBlobFeedUrl=https://dotnetfeed.blob.core.windows.net/dotnet-core/index.json
+             /p:DotNetPublishToBlobFeed=$(_DotNetPublishToBlobFeed)
+             /p:DotNetPublishUsingPipelines=$(_PublishUsingPipelines)
+             /p:DotNetArtifactsCategory=$(_DotNetArtifactsCategory)
+  - ${{ if eq(variables['Build.Reason'], 'PullRequest') }}:
+    - name: _BuildArgs
+      value: ''
+    - name: _SignType
+      valule: test
+    - name: _PublishArgs
+      value: ''
 
-    - script: ./build.cmd
-          -ci
-          -arch x64
-          -pack
-          -all
-          -buildNative
-          /bl:artifacts/log/build.x64.binlog
-          $(_BuildArgs)
-      displayName: Build x64
-    # TODO: make it possible to build for one Windows architecture at a time
-    # This is going to actually build x86 native assets. See https://github.com/aspnet/AspNetCore/issues/7196
+stages:
+- stage: build
+  displayName: Build
+  jobs:
+  # Code check
+  - template: jobs/default-build.yml
+    parameters:
+      jobName: Code_check
+      jobDisplayName: Code check
+      agentOs: Windows
+      steps:
+      - powershell: ./eng/scripts/CodeCheck.ps1 -ci
+        displayName: Run eng/scripts/CodeCheck.ps1
+      artifacts:
+      - name: Code_Check_Logs
+        path: artifacts/log/
+        publishOnError: true
+        includeForks: true
 
-    # Build the x86 shared framework
-    - script: ./build.cmd
-            -ci
-            -arch x86
-            -pack
-            -all
-            -buildNative
-            -noBuildJava
-            /p:OnlyPackPlatformSpecificPackages=true
-            /bl:artifacts/log/build.x86.binlog
-            $(_BuildArgs)
-      displayName: Build x86
+  # Build Windows (x64/x86)
+  - template: jobs/default-build.yml
+    parameters:
+      codeSign: true
+      jobName: Windows_build
+      jobDisplayName: "Build: Windows x64/x86"
+      agentOs: Windows
+      steps:
+      - script: "echo ##vso[build.addbuildtag]daily-build"
+        condition: and(ne(variables['Build.Reason'], 'PullRequest'), notin(variables['DotNetFinalVersionKind'], 'release', 'prerelease'))
+        displayName: 'Set CI tags'
+      - script: "echo ##vso[build.addbuildtag]release-candidate"
+        condition: and(ne(variables['Build.Reason'], 'PullRequest'), in(variables['DotNetFinalVersionKind'], 'release', 'prerelease'))
+        displayName: 'Set CI tags'
 
-    # This is in a separate build step with -forceCoreMsbuild to workaround MAX_PATH limitations - https://github.com/Microsoft/msbuild/issues/53
-    - script: .\src\SiteExtensions\build.cmd
-            -ci
-            -pack
-            -noBuildDeps
-            $(_BuildArgs)
-      condition: ne(variables['Build.Reason'], 'PullRequest')
-      displayName: Build SiteExtension
+      # !!! NOTE !!! Some of these steps have disabled code signing.
+      # This is intentional to workaround https://github.com/dotnet/arcade/issues/1957 which always re-submits for code-signing, even
+      # if they have already been signed. This results in slower builds due to re-submitting the same .nupkg many times for signing.
+      # The sign settings have been configured to
 
-    # This runs code-signing on all packages, zips, and jar files as defined in build/CodeSign.targets. If https://github.com/dotnet/arcade/issues/1957 is resolved,
-    # consider running code-signing inline with the other previous steps.
-    # Sign check is disabled because it is run in a separate step below, after installers are built.
-    - script: ./build.cmd
-              -ci
-              -noBuild
-              -noRestore
-              -sign
-              /bl:artifacts/log/build.codesign.binlog
-              $(_BuildArgs)
-      displayName: Code sign packages
+      - script: ./build.cmd
+                -ci
+                -arch x64
+                -pack
+                -all
+                -buildNative
+                /bl:artifacts/log/build.x64.binlog
+                $(_BuildArgs)
+        displayName: Build x64
 
-    # Windows installers bundle both x86 and x64 assets
-    - script: ./build.cmd
-            -ci
-            -sign
-            -buildInstallers
-            /bl:artifacts/log/installers.msbuild.binlog
-            $(_BuildArgs)
-      displayName: Build Installers
+      # Build the x86 shared framework
+      # TODO: make it possible to build for one Windows architecture at a time
+      # This is going to actually build x86 native assets. See https://github.com/aspnet/AspNetCore/issues/7196
+      - script: ./build.cmd
+                -ci
+                -arch x86
+                -pack
+                -all
+                -buildNative
+                -noBuildJava
+                /p:OnlyPackPlatformSpecificPackages=true
+                /bl:artifacts/log/build.x86.binlog
+                $(_BuildArgs)
+        displayName: Build x86
 
-    artifacts:
-    - name: Windows_Logs
-      path: artifacts/log/
-      publishOnError: true
-    - name: Windows_Packages
-      path: artifacts/packages/
-    - name: Windows_Symbols
-      path: artifacts/symbols/
-    - name: Windows_VSIX
-      path: artifacts/VSSetup/
-    - name: Windows_Manifests
-      path: artifacts/manifests/
-    - name: Windows_Installers
-      path: artifacts/installers/
+      # This is in a separate build step with -forceCoreMsbuild to workaround MAX_PATH limitations - https://github.com/Microsoft/msbuild/issues/53
+      - script: .\src\SiteExtensions\build.cmd
+                -ci
+                -pack
+                -noBuildDeps
+                $(_BuildArgs)
+        condition: ne(variables['Build.Reason'], 'PullRequest')
+        displayName: Build SiteExtension
 
-# Build Windows ARM
-- template: jobs/default-build.yml
-  parameters:
-    codeSign: true
-    jobName: Windows_arm_build
-    jobDisplayName: "Build: Windows ARM"
-    agentOs: Windows
-    buildArgs:
-      -arch arm
-      -sign
-      -pack
-      -noBuildNodeJS
-      -noBuildJava
-      /p:OnlyPackPlatformSpecificPackages=true
-      /bl:artifacts/log/build.win-arm.binlog
-      $(_BuildArgs)
-    installNodeJs: false
-    installJdk: false
-    artifacts:
-    - name: Windows_arm_Packages
-      path: artifacts/packages/
-    - name: Windows_arm_Manifests
-      path: artifacts/manifests/
-    - name: Windows_arm_Installers
-      path: artifacts/installers/
-    - name: Windows_arm_Logs
-      path: artifacts/log/
-      publishOnError: true
+      # This runs code-signing on all packages, zips, and jar files as defined in build/CodeSign.targets. If https://github.com/dotnet/arcade/issues/1957 is resolved,
+      # consider running code-signing inline with the other previous steps.
+      # Sign check is disabled because it is run in a separate step below, after installers are built.
+      - script: ./build.cmd
+                -ci
+                -noBuild
+                -noRestore
+                -sign
+                /bl:artifacts/log/build.codesign.binlog
+                /p:DotNetSignType=$(_SignType)
+                $(_BuildArgs)
+        displayName: Code sign packages
 
-# Build MacOS
-- template: jobs/default-build.yml
-  parameters:
-    jobName: MacOs_x64_build
-    jobDisplayName: "Build: macOS"
-    agentOs: macOs
-    buildArgs:
-      --pack
-      --all
-      --no-build-nodejs
-      --no-build-java
-      -p:OnlyPackPlatformSpecificPackages=true
-      -bl:artifacts/log/build.macos.binlog
-      $(_BuildArgs)
-    installNodeJs: false
-    installJdk: false
-    artifacts:
-    - name: MacOS_x64_Packages
-      path: artifacts/packages/
-    - name: MacOS_x64_Manifests
-      path: artifacts/manifests/
-    - name: MacOS_x64_Installers
-      path: artifacts/installers/
-    - name: MacOS_x64_Logs
-      path: artifacts/log/
-      publishOnError: true
-- template: jobs/codesign-xplat.yml
-  parameters:
-    inputName: MacOS_x64
+      # Windows installers bundle both x86 and x64 assets
+      - script: ./build.cmd
+                -ci
+                -sign
+                -buildInstallers
+                /bl:artifacts/log/installers.msbuild.binlog
+                /p:DotNetSignType=$(_SignType)
+                /p:AssetManifestFileName=aspnetcore-win-x64-x86.xml
+                $(_BuildArgs)
+                $(_PublishArgs)
+                /p:PublishInstallerBaseVersion=true
+        displayName: Build Installers
 
-# Build Linux x64
-- template: jobs/default-build.yml
-  parameters:
-    jobName: Linux_x64_build
-    jobDisplayName: "Build: Linux x64"
-    agentOs: Linux
-    steps:
-    - script: ./build.sh
-          --ci
-          --arch x64
-          --pack
-          --all
-          --no-build-nodejs
-          --no-build-java
-          -p:OnlyPackPlatformSpecificPackages=true
-          -bl:artifacts/log/build.linux-x64.binlog
-          $(_BuildArgs)
-      displayName: Run build.sh
-    - script: |
-        git clean -xfd src/**/obj/
-        ./dockerbuild.sh bionic \
-          --ci \
-          --arch x64 \
-          --build-installers \
-          --no-build-deps \
-          --no-build-nodejs \
-          -p:OnlyPackPlatformSpecificPackages=true \
-          -p:BuildRuntimeArchive=false \
-          -p:LinuxInstallerType=deb \
-          -bl:artifacts/log/build.deb.binlog \
-          $(_BuildArgs)
-      displayName: Build Debian installers
-    - script: |
-        git clean -xfd src/**/obj/
-        ./dockerbuild.sh rhel \
-          --ci \
-          --arch x64 \
-          --build-installers \
-          --no-build-deps \
-          --no-build-nodejs \
-          -p:OnlyPackPlatformSpecificPackages=true \
-          -p:BuildRuntimeArchive=false \
-          -p:LinuxInstallerType=rpm \
-          -bl:artifacts/log/build.rpm.binlog \
-          $(_BuildArgs)
-      displayName: Build RPM installers
-    installNodeJs: false
-    installJdk: false
-    artifacts:
-    - name: Linux_x64_Packages
-      path: artifacts/packages/
-    - name: Linux_x64_Manifests
-      path: artifacts/manifests/
-    - name: Linux_x64_Installers
-      path: artifacts/installers/
-    - name: Linux_x64_Logs
-      path: artifacts/log/
-      publishOnError: true
-- template: jobs/codesign-xplat.yml
-  parameters:
-    inputName: Linux_x64
+      # A few files must also go to the VS package feed.
+      - ${{ if and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}:
+        - task: NuGetCommand@2
+          displayName: Push Visual Studio packages
+          inputs:
+            command: push
+            packagesToPush: 'artifacts/packages/**/VS.Redist.Common.AspNetCore.*.nupkg'
+            nuGetFeedType: external
+            publishFeedCredentials: 'DevDiv - VS package feed'
 
-# Build Linux ARM
-- template: jobs/default-build.yml
-  parameters:
-    jobName: Linux_arm_build
-    jobDisplayName: "Build: Linux ARM"
-    agentOs: Linux
-    buildArgs:
-      --arch arm
-      --pack
-      --all
-      --no-build-nodejs
-      --no-build-java
-      -p:OnlyPackPlatformSpecificPackages=true
-      -bl:artifacts/log/build.linux-arm.binlog
-      $(_BuildArgs)
-    installNodeJs: false
-    installJdk: false
-    artifacts:
-    - name: Linux_arm_Packages
-      path: artifacts/packages/
-    - name: Linux_arm_Manifests
-      path: artifacts/manifests/
-    - name: Linux_arm_Installers
-      path: artifacts/installers/
-    - name: Linux_arm_Logs
-      path: artifacts/log/
-      publishOnError: true
-- template: jobs/codesign-xplat.yml
-  parameters:
-    inputName: Linux_arm
+      artifacts:
+      - name: Windows_Logs
+        path: artifacts/log/
+        publishOnError: true
+        includeForks: true
+      - name: Windows_Packages
+        path: artifacts/packages/
 
-# Build Linux ARM64
-- template: jobs/default-build.yml
-  parameters:
-    jobName: Linux_arm64_build
-    jobDisplayName: "Build: Linux ARM64"
-    agentOs: Linux
-    buildArgs:
-      --arch arm64
-      --all
-      --pack
-      --no-build-nodejs
-      --no-build-java
-      -p:OnlyPackPlatformSpecificPackages=true
-      -bl:artifacts/log/build.arm64.binlog
-      $(_BuildArgs)
-    installNodeJs: false
-    installJdk: false
-    artifacts:
-    - name: Linux_arm64_Packages
-      path: artifacts/packages/
-    - name: Linux_arm64_Manifests
-      path: artifacts/manifests/
-    - name: Linux_arm64_Installers
-      path: artifacts/installers/
-    - name: Linux_arm64_Logs
-      path: artifacts/log/
-      publishOnError: true
-- template: jobs/codesign-xplat.yml
-  parameters:
-    inputName: Linux_arm64
+  # Build Windows ARM
+  - template: jobs/default-build.yml
+    parameters:
+      codeSign: true
+      jobName: Windows_arm_build
+      jobDisplayName: "Build: Windows ARM"
+      agentOs: Windows
+      buildArgs:
+        -arch arm
+        -sign
+        -pack
+        -noBuildNodeJS
+        -noBuildJava
+        /bl:artifacts/log/build.win-arm.binlog
+        /p:DotNetSignType=$(_SignType)
+        /p:OnlyPackPlatformSpecificPackages=true
+        /p:AssetManifestFileName=aspnetcore-win-arm.xml
+        $(_BuildArgs)
+        $(_PublishArgs)
+      installNodeJs: false
+      installJdk: false
+      artifacts:
+      - name: Windows_arm_Logs
+        path: artifacts/log/
+        publishOnError: true
+        includeForks: true
+      - name: Windows_arm_Packages
+        path: artifacts/packages/
 
-# Build Linux Musl x64
-- template: jobs/default-build.yml
-  parameters:
-    jobName: Linux_musl_x64_build
-    jobDisplayName: "Build: Linux Musl x64"
-    agentOs: Linux
-    buildScript: ./dockerbuild.sh alpine
-    buildArgs:
-      --ci
-      --arch x64
-      --os-name linux-musl
-      --pack
-      --all
-      --no-build-nodejs
-      --no-build-java
-      -p:OnlyPackPlatformSpecificPackages=true
-      -bl:artifacts/log/build.musl.binlog
-      $(_BuildArgs)
-    installNodeJs: false
-    installJdk: false
-    artifacts:
-    - name: Linux_musl_x64_Packages
-      path: artifacts/packages/
-    - name: Linux_musl_x64_Manifests
-      path: artifacts/manifests/
-    - name: Linux_musl_x64_Installers
-      path: artifacts/installers/
-    - name: Linux_musl_x64_Logs
-      path: artifacts/log/
-      publishOnError: true
-- template: jobs/codesign-xplat.yml
-  parameters:
-    inputName: Linux_musl_x64
+  # Build MacOS
+  - template: jobs/default-build.yml
+    parameters:
+      jobName: MacOs_x64_build
+      jobDisplayName: "Build: macOS"
+      agentOs: macOs
+      buildArgs:
+        --pack
+        --all
+        --no-build-nodejs
+        --no-build-java
+        -p:OnlyPackPlatformSpecificPackages=true
+        -bl:artifacts/log/build.macos.binlog
+        -p:AssetManifestFileName=aspnetcore-MacOS_x64.xml
+        $(_BuildArgs)
+        $(_PublishArgs)
+      installNodeJs: false
+      installJdk: false
+      artifacts:
+      - name: MacOS_x64_Logs
+        path: artifacts/log/
+        publishOnError: true
+        includeForks: true
+      - name: MacOS_x64_Packages
+        path: artifacts/packages/
+  - template: jobs/codesign-xplat.yml
+    parameters:
+      inputName: MacOS_x64
 
-# Build Linux Musl ARM64
-- template: jobs/default-build.yml
-  parameters:
-    jobName: Linux_musl_arm64_build
-    jobDisplayName: "Build: Linux Musl ARM64"
-    agentOs: Linux
-    buildScript: ./dockerbuild.sh ubuntu-alpine37
-    buildArgs:
-      --ci
-      --arch arm64
-      --os-name linux-musl
-      --pack
-      --all
-      --no-build-nodejs
-      --no-build-java
-      -p:OnlyPackPlatformSpecificPackages=true
-      -bl:artifacts/log/build.musl.binlog
-      $(_BuildArgs)
-    installNodeJs: false
-    installJdk: false
-    artifacts:
-    - name: Linux_musl_arm64_Packages
-      path: artifacts/packages/
-    - name: Linux_musl_arm64_Manifests
-      path: artifacts/manifests/
-    - name: Linux_musl_arm64_Installers
-      path: artifacts/installers/
-    - name: Linux_musl_arm64_Logs
-      path: artifacts/log/
-      publishOnError: true
-- template: jobs/codesign-xplat.yml
-  parameters:
-    inputName: Linux_musl_arm64
+  # Build Linux x64
+  - template: jobs/default-build.yml
+    parameters:
+      jobName: Linux_x64_build
+      jobDisplayName: "Build: Linux x64"
+      agentOs: Linux
+      steps:
+      - script: ./build.sh
+            --ci
+            --arch x64
+            --pack
+            --all
+            --no-build-nodejs
+            --no-build-java
+            -p:OnlyPackPlatformSpecificPackages=true
+            -bl:artifacts/log/build.linux-x64.binlog
+            $(_BuildArgs)
+        displayName: Run build.sh
+      - script: |
+          git clean -xfd src/**/obj/
+          ./dockerbuild.sh bionic \
+            --ci \
+            --arch x64 \
+            --build-installers \
+            --no-build-deps \
+            --no-build-nodejs \
+            -p:OnlyPackPlatformSpecificPackages=true \
+            -p:BuildRuntimeArchive=false \
+            -p:LinuxInstallerType=deb \
+            -bl:artifacts/log/build.deb.binlog \
+            $(_BuildArgs)
+        displayName: Build Debian installers
+      - script: |
+          git clean -xfd src/**/obj/
+          ./dockerbuild.sh rhel \
+            --ci \
+            --arch x64 \
+            --build-installers \
+            --no-build-deps \
+            --no-build-nodejs \
+            -p:OnlyPackPlatformSpecificPackages=true \
+            -p:BuildRuntimeArchive=false \
+            -p:LinuxInstallerType=rpm \
+            -bl:artifacts/log/build.rpm.binlog \
+            -p:AssetManifestFileName=aspnetcore-Linux_x64.xml \
+            $(_BuildArgs) \
+            $(_PublishArgs)
+        displayName: Build RPM installers
+      installNodeJs: false
+      installJdk: false
+      artifacts:
+      - name: Linux_x64_Logs
+        path: artifacts/log/
+        publishOnError: true
+        includeForks: true
+      - name: Linux_x64_Packages
+        path: artifacts/packages/
+  - template: jobs/codesign-xplat.yml
+    parameters:
+      inputName: Linux_x64
 
-# Test jobs
-- template: jobs/default-build.yml
-  parameters:
-    condition: ne(variables['SkipTests'], 'true')
-    jobName: Windows_Test
-    jobDisplayName: "Test: Windows Server 2016 x64"
-    agentOs: Windows
-    isTestingJob: true
-    buildArgs: -all -pack -test -BuildNative "/p:SkipIISNewHandlerTests=true /p:SkipIISTests=true /p:SkipIISExpressTests=true /p:SkipIISNewShimTests=true /p:RunTemplateTests=false"
-    beforeBuild:
-    - powershell: "& ./src/Servers/IIS/tools/UpdateIISExpressCertificate.ps1; & ./src/Servers/IIS/tools/update_schema.ps1"
-      displayName: Setup IISExpress test certificates and schema
-    afterBuild:
-    - powershell: "& ./build.ps1 -CI -NoBuild -Test /p:RunFlakyTests=true"
-      displayName: Run Flaky Tests
-      continueOnError: true
-    artifacts:
-    - name: Windows_Test_Logs
-      path: artifacts/log/
-      publishOnError: true
-    - name: Windows_Test_Results
-      path: artifacts/TestResults/
-      publishOnError: true
+  # Build Linux ARM
+  - template: jobs/default-build.yml
+    parameters:
+      jobName: Linux_arm_build
+      jobDisplayName: "Build: Linux ARM"
+      agentOs: Linux
+      buildArgs:
+        --arch arm
+        --pack
+        --all
+        --no-build-nodejs
+        --no-build-java
+        -p:OnlyPackPlatformSpecificPackages=true
+        -bl:artifacts/log/build.linux-arm.binlog
+        -p:AssetManifestFileName=aspnetcore-Linux_arm.xml
+        $(_BuildArgs)
+        $(_PublishArgs)
+      installNodeJs: false
+      installJdk: false
+      artifacts:
+      - name: Linux_arm_Logs
+        path: artifacts/log/
+        publishOnError: true
+        includeForks: true
+      - name: Linux_arm_Packages
+        path: artifacts/packages/
+  - template: jobs/codesign-xplat.yml
+    parameters:
+      inputName: Linux_arm
 
-- template: jobs/default-build.yml
-  parameters:
-    condition: ne(variables['SkipTests'], 'true')
-    jobName: Windows_Templates_Test
-    jobDisplayName: "Test: Templates - Windows Server 2016 x64"
-    agentOs: Windows
-    isTestingJob: true
-    steps:
-    - script: ./build.cmd -ci -all -pack
-      displayName: Build Repo
-    - script: ./src/ProjectTemplates/build.cmd -ci -pack -NoRestore -NoBuilddeps "/p:RunTemplateTests=true /bl:artifacts/log/template.pack.binlog"
-      displayName: Pack Templates
-    - script: ./src/ProjectTemplates/build.cmd -ci -test -NoRestore -NoBuild -NoBuilddeps "/p:RunTemplateTests=true /bl:artifacts/log/template.test.binlog"
-      displayName: Test Templates
-    artifacts:
-    - name: Windows_Test_Templates_Logs
-      path: artifacts/log/
-      publishOnError: true
-    - name: Windows_Test_Templates_Results
-      path: artifacts/TestResults/
-      publishOnError: true
+  # Build Linux ARM64
+  - template: jobs/default-build.yml
+    parameters:
+      jobName: Linux_arm64_build
+      jobDisplayName: "Build: Linux ARM64"
+      agentOs: Linux
+      buildArgs:
+        --arch arm64
+        --all
+        --pack
+        --no-build-nodejs
+        --no-build-java
+        -p:OnlyPackPlatformSpecificPackages=true
+        -bl:artifacts/log/build.arm64.binlog
+        -p:AssetManifestFileName=aspnetcore-Linux_arm64.xml
+        $(_BuildArgs)
+        $(_PublishArgs)
+      installNodeJs: false
+      installJdk: false
+      artifacts:
+      - name: Linux_arm64_Logs
+        path: artifacts/log/
+        publishOnError: true
+        includeForks: true
+      - name: Linux_arm64_Packages
+        path: artifacts/packages/
+  - template: jobs/codesign-xplat.yml
+    parameters:
+      inputName: Linux_arm64
 
-- template: jobs/default-build.yml
-  parameters:
-    condition: ne(variables['SkipTests'], 'true')
-    jobName: MacOs_Test
-    jobDisplayName: "Test: macOS 10.13"
-    agentOs: macOs
-    isTestingJob: true
-    buildArgs: --all --test "/p:RunTemplateTests=false"
-    beforeBuild:
-    - bash: "./eng/scripts/install-nginx-mac.sh"
-      displayName: Installing Nginx
-    afterBuild:
-    - bash: ./build.sh --ci --pack --no-build --no-restore --no-build-deps "/bl:artifacts/log/packages.pack.binlog"
-      displayName: Pack Packages (for Template tests)
-    - bash: ./src/ProjectTemplates/build.sh --ci --pack --no-restore --no-build-deps "/bl:artifacts/log/template.pack.binlog"
-      displayName: Pack Templates (for Template tests)
-    - bash: ./build.sh --no-build --ci --test -p:RunFlakyTests=true
-      displayName: Run Flaky Tests
-      continueOnError: true
-    artifacts:
-    - name: MacOS_Test_Logs
-      path: artifacts/log/
-      publishOnError: true
-    - name: MacOS_Test_Results
-      path: artifacts/TestResults/
-      publishOnError: true
+  # Build Linux Musl x64
+  - template: jobs/default-build.yml
+    parameters:
+      jobName: Linux_musl_x64_build
+      jobDisplayName: "Build: Linux Musl x64"
+      agentOs: Linux
+      buildScript: ./dockerbuild.sh alpine
+      buildArgs:
+        --ci
+        --arch x64
+        --os-name linux-musl
+        --pack
+        --all
+        --no-build-nodejs
+        --no-build-java
+        -p:OnlyPackPlatformSpecificPackages=true
+        -bl:artifacts/log/build.musl.binlog
+        -p:AssetManifestFileName=aspnetcore-Linux_musl_x64.xml
+        $(_BuildArgs)
+        $(_PublishArgs)
+      installNodeJs: false
+      installJdk: false
+      artifacts:
+      - name: Linux_musl_x64_Logs
+        path: artifacts/log/
+        publishOnError: true
+        includeForks: true
+      - name: Linux_musl_x64_Packages
+        path: artifacts/packages/
+  - template: jobs/codesign-xplat.yml
+    parameters:
+      inputName: Linux_musl_x64
 
-- template: jobs/default-build.yml
-  parameters:
-    condition: ne(variables['SkipTests'], 'true')
-    jobName: Linux_Test
-    jobDisplayName: "Test: Ubuntu 16.04 x64"
-    agentOs: Linux
-    isTestingJob: true
-    buildArgs: --all --test "/p:RunTemplateTests=false"
-    beforeBuild:
-    - bash: "./eng/scripts/install-nginx-linux.sh"
-      displayName: Installing Nginx
-    - bash: "echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.conf && sudo sysctl -p"
-      displayName: Increase inotify limit
-    afterBuild:
-    - bash: ./build.sh --ci --pack --no-build --no-restore --no-build-deps "/bl:artifacts/log/packages.pack.binlog"
-      displayName: Pack Packages (for Template tests)
-    - bash: ./src/ProjectTemplates/build.sh --ci --pack --no-restore --no-build-deps "/bl:artifacts/log/template.pack.binlog"
-      displayName: Pack Templates (for Template tests)
-    - bash: ./build.sh --no-build --ci --test -p:RunFlakyTests=true
-      displayName: Run Flaky Tests
-      continueOnError: true
-    artifacts:
-    - name: Linux_Test_Logs
-      path: artifacts/log/
-      publishOnError: true
-    - name: Linux_Test_Results
-      path: artifacts/TestResults/
-      publishOnError: true
+  # Build Linux Musl ARM64
+  - template: jobs/default-build.yml
+    parameters:
+      jobName: Linux_musl_arm64_build
+      jobDisplayName: "Build: Linux Musl ARM64"
+      agentOs: Linux
+      buildScript: ./dockerbuild.sh ubuntu-alpine37
+      buildArgs:
+        --ci
+        --arch arm64
+        --os-name linux-musl
+        --pack
+        --all
+        --no-build-nodejs
+        --no-build-java
+        -p:OnlyPackPlatformSpecificPackages=true
+        -bl:artifacts/log/build.musl.binlog
+        -p:AssetManifestFileName=aspnetcore-Linux_musl_arm64.xml
+        $(_BuildArgs)
+        $(_PublishArgs)
+      installNodeJs: false
+      installJdk: false
+      artifacts:
+      - name: Linux_musl_arm64_Logs
+        path: artifacts/log/
+        publishOnError: true
+        includeForks: true
+      - name: Linux_musl_arm64_Packages
+        path: artifacts/packages/
+  - template: jobs/codesign-xplat.yml
+    parameters:
+      inputName: Linux_musl_arm64
+
+  # Test jobs
+  - template: jobs/default-build.yml
+    parameters:
+      condition: ne(variables['SkipTests'], 'true')
+      jobName: Windows_Test
+      jobDisplayName: "Test: Windows Server 2016 x64"
+      agentOs: Windows
+      isTestingJob: true
+      buildArgs: -all -pack -test -BuildNative "/p:SkipIISNewHandlerTests=true /p:SkipIISTests=true /p:SkipIISExpressTests=true /p:SkipIISNewShimTests=true /p:RunTemplateTests=false"
+      beforeBuild:
+      - powershell: "& ./src/Servers/IIS/tools/UpdateIISExpressCertificate.ps1; & ./src/Servers/IIS/tools/update_schema.ps1"
+        displayName: Setup IISExpress test certificates and schema
+      afterBuild:
+      - powershell: "& ./build.ps1 -CI -NoBuild -Test /p:RunFlakyTests=true"
+        displayName: Run Flaky Tests
+        continueOnError: true
+      - task: PublishTestResults@2
+        displayName: Publish Flaky Test Results
+        inputs:
+          testResultsFormat: 'xUnit'
+          testResultsFiles: '*.xml'
+          searchFolder: '$(Build.SourcesDirectory)/artifacts/TestResults/$(_BuildConfig)/Flaky'
+      artifacts:
+      - name: Windows_Test_Logs
+        path: artifacts/log/
+        publishOnError: true
+        includeForks: true
+      - name: Windows_Test_Results
+        path: artifacts/TestResults/
+        publishOnError: true
+        includeForks: true
+
+  - template: jobs/default-build.yml
+    parameters:
+      condition: ne(variables['SkipTests'], 'true')
+      jobName: Windows_Templates_Test
+      jobDisplayName: "Test: Templates - Windows Server 2016 x64"
+      agentOs: Windows
+      isTestingJob: true
+      steps:
+      - script: ./build.cmd -ci -all -pack
+        displayName: Build Repo
+      - script: ./src/ProjectTemplates/build.cmd -ci -pack -NoRestore -NoBuilddeps "/p:RunTemplateTests=true /bl:artifacts/log/template.pack.binlog"
+        displayName: Pack Templates
+      - script: ./src/ProjectTemplates/build.cmd -ci -test -NoRestore -NoBuild -NoBuilddeps "/p:RunTemplateTests=true /bl:artifacts/log/template.test.binlog"
+        displayName: Test Templates
+      artifacts:
+      - name: Windows_Test_Templates_Logs
+        path: artifacts/log/
+        publishOnError: true
+        includeForks: true
+      - name: Windows_Test_Templates_Results
+        path: artifacts/TestResults/
+        publishOnError: true
+        includeForks: true
 
-# Helix ARM64
-- template: jobs/default-build.yml
-  parameters:
-    jobName: Helix_arm64
-    jobDisplayName: "Tests: Helix ARM64"
-    agentOs: Linux
-    timeoutInMinutes: 240
+  - template: jobs/default-build.yml
+    parameters:
+      condition: ne(variables['SkipTests'], 'true')
+      jobName: MacOS_Test
+      jobDisplayName: "Test: macOS 10.13"
+      agentOs: macOS
+      isTestingJob: true
+      buildArgs: --all --test "/p:RunTemplateTests=false"
+      beforeBuild:
+      - bash: "./eng/scripts/install-nginx-mac.sh"
+        displayName: Installing Nginx
+      afterBuild:
+      - bash: ./build.sh --ci --pack --no-build --no-restore --no-build-deps "/bl:artifacts/log/packages.pack.binlog"
+        displayName: Pack Packages (for Template tests)
+      - bash: ./src/ProjectTemplates/build.sh --ci --pack --no-restore --no-build-deps "/bl:artifacts/log/template.pack.binlog"
+        displayName: Pack Templates (for Template tests)
+      - bash: ./build.sh --no-build --ci --test -p:RunFlakyTests=true
+        displayName: Run Flaky Tests
+        continueOnError: true
+      - task: PublishTestResults@2
+        displayName: Publish Flaky Test Results
+        inputs:
+          testResultsFormat: 'xUnit'
+          testResultsFiles: '*.xml'
+          searchFolder: '$(Build.SourcesDirectory)/artifacts/TestResults/$(_BuildConfig)/Flaky'
+      artifacts:
+      - name: MacOS_Test_Logs
+        path: artifacts/log/
+        publishOnError: true
+        includeForks: true
+      - name: MacOS_Test_Results
+        path: artifacts/TestResults/
+        publishOnError: true
+        includeForks: true
+
+  - template: jobs/default-build.yml
+    parameters:
+      condition: ne(variables['SkipTests'], 'true')
+      jobName: Linux_Test
+      jobDisplayName: "Test: Ubuntu 16.04 x64"
+      agentOs: Linux
+      isTestingJob: true
+      buildArgs: --all --test "/p:RunTemplateTests=false"
+      beforeBuild:
+      - bash: "./eng/scripts/install-nginx-linux.sh"
+        displayName: Installing Nginx
+      - bash: "echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.conf && sudo sysctl -p"
+        displayName: Increase inotify limit
+      afterBuild:
+      - bash: ./build.sh --ci --pack --no-build --no-restore --no-build-deps "/bl:artifacts/log/packages.pack.binlog"
+        displayName: Pack Packages (for Template tests)
+      - bash: ./src/ProjectTemplates/build.sh --ci --pack --no-restore --no-build-deps "/bl:artifacts/log/template.pack.binlog"
+        displayName: Pack Templates (for Template tests)
+      - bash: ./build.sh --no-build --ci --test -p:RunFlakyTests=true
+        displayName: Run Flaky Tests
+        continueOnError: true
+      - task: PublishTestResults@2
+        displayName: Publish Flaky Test Results
+        inputs:
+          testResultsFormat: 'xUnit'
+          testResultsFiles: '*.xml'
+          searchFolder: '$(Build.SourcesDirectory)/artifacts/TestResults/$(_BuildConfig)/Flaky'
+      artifacts:
+      - name: Linux_Test_Logs
+        path: artifacts/log/
+        publishOnError: true
+        includeForks: true
+      - name: Linux_Test_Results
+        path: artifacts/TestResults/
+        publishOnError: true
+        includeForks: true
+
+  # Helix ARM64
+  - template: jobs/default-build.yml
+    parameters:
+      jobName: Helix_arm64
+      jobDisplayName: "Tests: Helix ARM64"
+      agentOs: Linux
+      timeoutInMinutes: 240
+      steps:
+      - script: ./restore.sh -ci
+        displayName: Restore
+      - script: ./build.sh -ci --arch arm64 -test --no-build-nodejs -projects $(Build.SourcesDirectory)/eng/helix/helix.proj /p:IsHelixJob=true /p:BuildAllProjects=true /p:BuildNative=true -bl
+        displayName: Run build.sh helix arm64 target
+        env:
+          SYSTEM_ACCESSTOKEN: $(System.AccessToken) # We need to set this env var to publish helix results to Azure Dev Ops
+      installNodeJs: false
+      artifacts:
+      - name: Helix_arm64_logs
+        path: artifacts/log/
+        publishOnError: true
+        includeForks: true
+
+  # Source build
+  - job: Source_Build
+    displayName: 'Test: Linux Source Build'
+    container: centos:7
+    pool:
+      vmImage: 'ubuntu-16.04'
+    variables:
+      DotNetCoreSdkDir: $(Agent.ToolsDirectory)/dotnet
+      DOTNET_SYSTEM_GLOBALIZATION_INVARIANT: true
     steps:
-    - script: ./restore.sh -ci
-      displayName: Restore
-    - script: ./build.sh -ci --arch arm64 -test --no-build-nodejs -projects $(Build.SourcesDirectory)/eng/helix/helix.proj /p:IsHelixJob=true /p:BuildAllProjects=true /p:BuildNative=true -bl
-      displayName: Run build.sh helix arm64 target
-      env:
-        SYSTEM_ACCESSTOKEN: $(System.AccessToken) # We need to set this env var to publish helix results to Azure Dev Ops
-    installNodeJs: false
-    artifacts:
-    - name: Helix_arm64_logs
-      path: artifacts/log/
-      publishOnError: true
+    - script: |
+        source eng/common/native/common-library.sh
+        mkdir -p $HOME/bin
+        GetFile https://github.com/stedolan/jq/releases/download/jq-1.6/jq-linux64 $HOME/bin/jq
+        chmod +x $HOME/bin/jq
+        echo "##vso[task.prependpath]$HOME/bin"
+      displayName: Install jq
+    - script: ./eng/scripts/ci-source-build.sh --ci --configuration Release /p:BuildManaged=true /p:BuildNodeJs=false
+      displayName: Run ci-source-build.sh
+    - task: PublishBuildArtifacts@1
+      displayName: Upload logs
+      condition: always()
+      continueOnError: true
+      inputs:
+        pathtoPublish: artifacts/log/
+        artifactName: Source_Build_Logs
+        artifactType: Container
+        parallel: true
+    - task: PublishBuildArtifacts@1
+      displayName: Upload package artifacts
+      # Only capture source build artifacts in PRs for the sake of inspecting
+      # changes that impact source-build. The artifacts from this build pipeline are never actually used.
+      condition: and(succeeded(), eq(variables['Build.Reason'], 'PullRequest'))
+      inputs:
+        pathtoPublish: artifacts/packages/
+        artifactName: Source_Build_Packages
+        artifactType: Container
+        parallel: true
+
+  # Publish to the BAR
+  - ${{ if and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}:
+    - template: /eng/common/templates/job/publish-build-assets.yml
+      parameters:
+        dependsOn:
+          - Windows_build
+          - Windows_arm_build
+          - CodeSign_Xplat_MacOS_x64
+          - CodeSign_Xplat_Linux_x64
+          - CodeSign_Xplat_Linux_arm
+          - CodeSign_Xplat_Linux_arm64
+          - CodeSign_Xplat_Linux_musl_x64
+          - CodeSign_Xplat_Linux_musl_arm64
+          # In addition to the dependencies above, ensure the build was successful overall.
+          - Code_check
+          - Linux_Test
+          - MacOS_Test
+          - Source_Build
+          - Windows_Templates_Test
+          - Windows_Test
+        pool:
+          vmImage: vs2017-win2016
+        publishUsingPipelines: ${{ variables._PublishUsingPipelines }}
+        enablePublishBuildArtifacts: true # publish artifacts/log files
 
-# Source build
-- job: Source_Build
-  displayName: 'Test: Linux Source Build'
-  container: centos:7
-  pool:
-    vmImage: 'ubuntu-16.04'
-  variables:
-    DotNetCoreSdkDir: $(Agent.ToolsDirectory)/dotnet
-    DOTNET_SYSTEM_GLOBALIZATION_INVARIANT: true
-  steps:
-  - script: |
-      source eng/common/native/common-library.sh
-      mkdir -p $HOME/bin
-      GetFile https://github.com/stedolan/jq/releases/download/jq-1.6/jq-linux64 $HOME/bin/jq
-      chmod +x $HOME/bin/jq
-      echo "##vso[task.prependpath]$HOME/bin"
-    displayName: Install jq
-  - script: ./eng/scripts/ci-source-build.sh --ci --configuration Release /p:BuildManaged=true /p:BuildNodeJs=false
-    displayName: Run ci-source-build.sh
-  - task: PublishBuildArtifacts@1
-    displayName: Upload logs
-    condition: always()
-    continueOnError: true
-    inputs:
-      pathtoPublish: artifacts/log/
-      artifactName: Source_Build_Logs
-      artifactType: Container
-      parallel: true
-  - task: PublishBuildArtifacts@1
-    displayName: Upload package artifacts
-    # Only capture source build artifacts in PRs for the sake of inspecting
-    # changes that impact source-build. The artifacts from this build pipeline are never actually used.
-    condition: and(succeeded(), eq(variables['Build.Reason'], 'PullRequest'))
-    inputs:
-      pathtoPublish: artifacts/packages/
-      artifactName: Source_Build_Packages
-      artifactType: Container
-      parallel: true
+- ${{ if and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}:
+  - template: /eng/common/templates/post-build/post-build.yml
+    parameters:
+      # See https://github.com/dotnet/arcade/issues/2871
+      enableSymbolValidation: false
+      enableSigningValidation: false
+      publishInstallersAndChecksums: true

+ 24 - 6
.azure/pipelines/jobs/codesign-xplat.yml

@@ -19,13 +19,31 @@ jobs:
       displayName: Download ${{ parameters.inputName }} artifacts
       inputs:
         artifactName: ${{ parameters.inputName }}_Packages
-        downloadPath: $(Build.StagingDirectory)/deps/
+        downloadPath: $(Build.StagingDirectory)/downloaded_packages/
         itemPattern: '**/*.nupkg'
-    - task: MSBuild@1
-      displayName: Code-sign .nupkg files
+    - task: CopyFiles@2
+      displayName: Copy packages to ArtifactsShippingPackagesDir
       inputs:
-        solution: eng\tools\XplatPackageSigner\XplatPackageSigner.proj
-        msbuildArguments: /p:SignType=$(_SignType) /p:DirectoryToSign=$(Build.StagingDirectory)\deps\${{ parameters.inputName }}_Packages\
+        sourceFolder: $(Build.StagingDirectory)/downloaded_packages/
+        contents: '**/*.nupkg'
+        targetFolder: $(Build.SourcesDirectory)/artifacts/packages/$(BuildConfiguration)/shipping/
+        flattenFolders: true
+    - powershell: .\eng\common\build.ps1
+        -ci
+        -restore
+        -sign
+        -publish
+        -configuration $(BuildConfiguration)
+        -projects $(Build.SourcesDirectory)/eng/empty.proj
+        /p:AssetManifestFileName=aspnetcore-${{ parameters.inputName }}-signed.xml
+        /p:DotNetSignType=$(_SignType)
+        $(_BuildArgs)
+        $(_PublishArgs)
+      displayName: Sign and publish packages
     artifacts:
+    - name: CodeSign_Xplat_${{ parameters.inputName }}_Logs
+      path: artifacts/log/
+      publishOnError: true
+      includeForks: true
     - name: ${{ parameters.inputName }}_Packages_Signed
-      path: $(Build.StagingDirectory)\deps\${{ parameters.inputName }}_Packages\
+      path: artifacts/packages/

+ 168 - 190
.azure/pipelines/jobs/default-build.yml

@@ -5,10 +5,6 @@
 #       The name of the job. Defaults to the name of the OS. No spaces allowed
 #   jobDisplayName: string
 #       The friendly job name to display in the UI. Defaults to the name of the OS.
-#   poolName: string
-#       The name of the Azure DevOps agent pool to use.
-#   poolVmImage: string
-#       The name of a virtual machine image to use. Primarily of interest when using the Hosted pools.
 #   agentOs: string
 #       Used in templates to define variables which are OS specific. Typically from the set { Windows, Linux, macOS }
 #   buildArgs: string
@@ -21,20 +17,18 @@
 #   afterBuild: [steps]
 #       Additional steps to run after build.sh/cmd
 #   artifacts: [array]
-#    - path: string
-#           The file path to artifacts output
-#      includeForks: boolean
-#           Should artifacts from forks be published
-#      name: string
+#       name: string
 #           The name of the artifact container
-#   variables: { string: string }
-#     A map of custom variables
-#   matrix: { string: { string: string } }
-#     A map of matrix configurations and variables. https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=azure-devops&tabs=schema#job
+#    -  path: string
+#           The file path to artifacts output
+#       includeForks: boolean
+#           Should artifacts from forks be published?
+#       publishOnError: boolean
+#           Should artifacts be published if previous step failed?
 #   dependsOn: string | [ string ]
-#     For fan-out/fan-in. https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=azure-devops&tabs=schema#job
+#       For fan-out/fan-in. https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=azure-devops&tabs=schema#job
 #   condition: string
-#     A condition which can be used to skip the job completely
+#       A condition which can be used to skip the job completely
 #   codeSign: boolean
 #       This build definition is enabled for code signing. (Only applies to Windows)
 #   buildDirectory: string
@@ -48,20 +42,16 @@
 
 parameters:
   agentOs: 'Windows'
-  poolName: ''
-  poolVmImage: ''
   buildArgs: ''
   configuration: 'Release'
   beforeBuild: []
   # steps: []  don't define an empty object default because there is no way in template expression yet to check "if isEmpty(parameters.steps)"
   afterBuild: []
   codeSign: false
-  variables: {}
   dependsOn: ''
   condition: ''
   # jobName: '' - use agentOs by default.
   # jobDisplayName: '' - use agentOs by default.
-  # matrix: {} - don't define an empty object default because there is no way in template expression yet to check "if isEmpty(parameters.matrix)"
   artifacts:  []
   buildDirectory: ''
   buildScript: ''
@@ -75,182 +65,170 @@ parameters:
   cancelTimeoutInMinutes: 15
 
 jobs:
-- job: ${{ coalesce(parameters.jobName, parameters.agentOs) }}
-  displayName: ${{ coalesce(parameters.jobDisplayName, parameters.agentOs) }}
-  dependsOn: ${{ parameters.dependsOn }}
-  ${{ if ne(parameters.condition, '') }}:
-    condition: ${{ parameters.condition }}
-  timeoutInMinutes: ${{ parameters.timeoutInMinutes }}
-  workspace:
-    clean: all
-  strategy:
-    ${{ if ne(parameters.matrix, '') }}:
-      maxParallel: 8
-      matrix: ${{ parameters.matrix }}
-  # Map friendly OS names to the right queue
-  # See https://github.com/dotnet/arcade/blob/master/Documentation/ChoosingAMachinePool.md
-  pool:
-    ${{ if ne(parameters.poolVmImage, '') }}:
-      vmImage: ${{ parameters.poolVmImage }}
-    ${{ if and(eq(parameters.poolVmImage, ''), eq(parameters.agentOs, 'macOS')) }}:
-      vmImage: macOS-10.13
-    ${{ if and(eq(parameters.poolVmImage, ''), eq(parameters.agentOs, 'Linux')) }}:
-      vmImage: ubuntu-16.04
-    ${{ if ne(parameters.poolName, '') }}:
-      name: ${{ parameters.poolName }}
-    ${{ if and(eq(parameters.poolName, ''), eq(parameters.agentOs, 'Windows')) }}:
-      ${{ if eq(variables['System.TeamProject'], 'public') }}:
-        name: NetCorePublic-Pool
-        ${{ if ne(parameters.isTestingJob, true) }}:
-          # Visual Studio Build Tools
-          queue: BuildPool.Windows.10.Amd64.VS2019.BT.Open
-        ${{ if eq(parameters.isTestingJob, true) }}:
+- template: /eng/common/templates/job/job.yml
+  parameters:
+    name: ${{ coalesce(parameters.jobName, parameters.agentOs) }}
+    displayName: ${{ coalesce(parameters.jobDisplayName, parameters.agentOs) }}
+    dependsOn: ${{ parameters.dependsOn }}
+    ${{ if ne(parameters.condition, '') }}:
+      condition: ${{ parameters.condition }}
+    timeoutInMinutes: ${{ parameters.timeoutInMinutes }}
+    cancelTimeoutInMinutes: ${{ parameters.cancelTimeoutInMinutes }}
+    ${{ if and(eq(variables['System.TeamProject'], 'internal'), eq(parameters.agentOs, 'Windows'), eq(parameters.codeSign, 'true')) }}:
+      enableMicrobuild: true
+      enablePublishBuildAssets: true
+      enablePublishUsingPipelines: ${{ variables._PublishUsingPipelines }}
+    enablePublishTestResults: true # publish test results to AzDO (populates AzDO Tests tab)
+    enableTelemetry: true
+    helixRepo: aspnet/AspNetCore
+    helixType: build.product/
+    workspace:
+      clean: all
+    # Map friendly OS names to the right queue
+    # See https://github.com/dotnet/arcade/blob/master/Documentation/ChoosingAMachinePool.md
+    pool:
+      ${{ if eq(parameters.agentOs, 'macOS') }}:
+        vmImage: macOS-10.13
+      ${{ if eq(parameters.agentOs, 'Linux') }}:
+        vmImage: ubuntu-16.04
+      ${{ if eq(parameters.agentOs, 'Windows') }}:
+        ${{ if eq(variables['System.TeamProject'], 'public') }}:
+          name: NetCorePublic-Pool
+          ${{ if ne(parameters.isTestingJob, true) }}:
+            # Visual Studio Build Tools
+            queue: BuildPool.Windows.10.Amd64.VS2019.BT.Open
+          ${{ if eq(parameters.isTestingJob, true) }}:
+            # Visual Studio Enterprise - contains some stuff, like SQL Server and IIS Express, that we use for testing
+            queue: BuildPool.Windows.10.Amd64.VS2019.Open
+        ${{ if eq(variables['System.TeamProject'], 'internal') }}:
+          name: NetCoreInternal-Pool
           # Visual Studio Enterprise - contains some stuff, like SQL Server and IIS Express, that we use for testing
-          queue: BuildPool.Windows.10.Amd64.VS2019.Open
-      ${{ if eq(variables['System.TeamProject'], 'internal') }}:
-        name: NetCoreInternal-Pool
-        # Visual Studio Enterprise - contains some stuff, like SQL Server and IIS Express, that we use for testing
-        queue: BuildPool.Windows.10.Amd64.VS2019
-  variables:
-    AgentOsName: ${{ parameters.agentOs }}
-    ASPNETCORE_TEST_LOG_MAXPATH: "200" # Keep test log file name length low enough for artifact zipping
-    DOTNET_HOME: $(Build.SourcesDirectory)/.dotnet
-    BuildScript: ${{ parameters.buildScript }}
-    BuildScriptArgs: ${{ parameters.buildArgs }}
-    BuildConfiguration: ${{ parameters.configuration }}
-    BuildDirectory: ${{ parameters.buildDirectory }}
-    DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true
-    TeamName: AspNetCore
-    ${{ if and(eq(parameters.installJdk, 'true'), eq(parameters.agentOs, 'Windows')) }}:
-      JAVA_HOME: $(Agent.BuildDirectory)\.tools\jdk\win-x64
-    ${{ if or(ne(parameters.codeSign, true), ne(variables['System.TeamProject'], 'internal')) }}:
-      _SignType: ''
-    ${{ if and(eq(parameters.codeSign, true), eq(variables['System.TeamProject'], 'internal')) }}:
-      ${{ if ne(variables['Build.Reason'], 'PullRequest') }}:
-        _SignType: real
-      ${{ if eq(variables['Build.Reason'], 'PullRequest') }}:
-        _SignType: test
-    ${{ insert }}: ${{ parameters.variables }}
-  steps:
-  - checkout: self
-    clean: true
-  - ${{ if eq(parameters.installNodeJs, 'true') }}:
-    - task: NodeTool@0
-      displayName: Install Node 10.x
-      inputs:
-        versionSpec: 10.x
-  - ${{ if eq(parameters.agentOs, 'Windows') }}:
-    - task: NuGetCommand@2
-      displayName: 'Clear NuGet caches'
-      condition: succeeded()
-      inputs:
-        command: custom
-        arguments: 'locals all -clear'
-  - ${{ if and(eq(parameters.installJdk, 'true'), eq(parameters.agentOs, 'Windows')) }}:
-    - powershell: ./eng/scripts/InstallJdk.ps1
-      displayName: Install JDK 11
-    - ${{ if eq(parameters.isTestingJob, true) }}:
-      - powershell: |
-          Write-Host "##vso[task.setvariable variable=SeleniumProcessTrackingFolder]$(BuildDirectory)\artifacts\tmp\selenium\"
-          ./eng/scripts/InstallGoogleChrome.ps1
-        displayName: Install Chrome
-  - ${{ if and(eq(variables['System.TeamProject'], 'internal'), eq(parameters.agentOs, 'Windows'), eq(parameters.codeSign, 'true')) }}:
-    - task: MicroBuildSigningPlugin@1
-      displayName: Install MicroBuild Signing plugin
-      condition: and(succeeded(), in(variables['_SignType'], 'test', 'real'))
-      inputs:
-        signType: $(_SignType)
-        zipSources: false
-        feedSource: https://dnceng.pkgs.visualstudio.com/_packaging/MicroBuildToolset/nuget/v3/index.json
+          queue: BuildPool.Windows.10.Amd64.VS2019
+    variables:
+    - AgentOsName: ${{ parameters.agentOs }}
+    - ASPNETCORE_TEST_LOG_MAXPATH: "200" # Keep test log file name length low enough for artifact zipping
+    - BuildScript: ${{ parameters.buildScript }}
+    - BuildScriptArgs: ${{ parameters.buildArgs }}
+    - _BuildConfig: ${{ parameters.configuration }}
+    - BuildConfiguration: ${{ parameters.configuration }}
+    - BuildDirectory: ${{ parameters.buildDirectory }}
+    - DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true
+    - TeamName: AspNetCore
+    - ${{ if and(eq(parameters.installJdk, 'true'), eq(parameters.agentOs, 'Windows')) }}:
+      - JAVA_HOME: $(Agent.BuildDirectory)\.tools\jdk\win-x64
+    - ${{ if or(ne(parameters.codeSign, true), ne(variables['System.TeamProject'], 'internal')) }}:
+      - _SignType: ''
+    - ${{ if and(eq(parameters.codeSign, true), eq(variables['System.TeamProject'], 'internal')) }}:
+      - ${{ if ne(variables['Build.Reason'], 'PullRequest') }}:
+        - _SignType: real
+      - ${{ if eq(variables['Build.Reason'], 'PullRequest') }}:
+        - _SignType: test
+    steps:
+    - checkout: self
+      clean: true
+    - ${{ if and(eq(parameters.agentOs, 'Windows'), eq(parameters.isTestingJob, true)) }}:
+      - powershell: ./eng/scripts/InstallProcDump.ps1
+        displayName: Install ProcDump
+      - powershell: ./eng/scripts/StartDumpCollectionForHangingBuilds.ps1 $(ProcDumpPath)procdump.exe artifacts/log/ (Get-Date).AddMinutes(160) dotnet
+        displayName: Start background dump collection
+    - ${{ if eq(parameters.installNodeJs, 'true') }}:
+      - task: NodeTool@0
+        displayName: Install Node 10.x
+        inputs:
+          versionSpec: 10.x
+    - ${{ if eq(parameters.agentOs, 'Windows') }}:
+      - task: NuGetCommand@2
+        displayName: 'Clear NuGet caches'
+        condition: succeeded()
+        inputs:
+          command: custom
+          arguments: 'locals all -clear'
+    - ${{ if and(eq(parameters.installJdk, 'true'), eq(parameters.agentOs, 'Windows')) }}:
+      - powershell: ./eng/scripts/InstallJdk.ps1
+        displayName: Install JDK 11
+      - ${{ if eq(parameters.isTestingJob, true) }}:
+        - powershell: |
+            Write-Host "##vso[task.setvariable variable=SeleniumProcessTrackingFolder]$(BuildDirectory)\artifacts\tmp\selenium\"
+            ./eng/scripts/InstallGoogleChrome.ps1
+          displayName: Install Chrome
 
-  - ${{ parameters.beforeBuild }}
+    - ${{ parameters.beforeBuild }}
 
-  - ${{ if ne(parameters.steps, '')}}:
-    - ${{ parameters.steps }}
-  - ${{ if eq(parameters.steps, '')}}:
-    - ${{ if eq(parameters.buildScript, '') }}:
-      - ${{ if eq(parameters.agentOs, 'Windows') }}:
-        - script: .\$(BuildDirectory)\build.cmd -ci /p:DotNetSignType=$(_SignType) -Configuration $(BuildConfiguration) $(BuildScriptArgs)
-          displayName: Run build.cmd
-      - ${{ if ne(parameters.agentOs, 'Windows') }}:
-        - script: ./$(BuildDirectory)/build.sh -ci -configuration $(BuildConfiguration) $(BuildScriptArgs)
-          displayName: Run build.sh
-    - ${{ if ne(parameters.buildScript, '') }}:
-      - script: $(BuildScript) -Configuration $(BuildConfiguration) $(BuildScriptArgs)
-        displayName: run $(BuildScript)
+    - ${{ if ne(parameters.steps, '')}}:
+      - ${{ parameters.steps }}
+    - ${{ if eq(parameters.steps, '')}}:
+      - ${{ if eq(parameters.buildScript, '') }}:
+        - ${{ if eq(parameters.agentOs, 'Windows') }}:
+          - script: .\$(BuildDirectory)\build.cmd -ci /p:DotNetSignType=$(_SignType) -Configuration $(BuildConfiguration) $(BuildScriptArgs)
+            displayName: Run build.cmd
+        - ${{ if ne(parameters.agentOs, 'Windows') }}:
+          - script: ./$(BuildDirectory)/build.sh -ci -configuration $(BuildConfiguration) $(BuildScriptArgs)
+            displayName: Run build.sh
+      - ${{ if ne(parameters.buildScript, '') }}:
+        - script: $(BuildScript) -Configuration $(BuildConfiguration) $(BuildScriptArgs)
+          displayName: run $(BuildScript)
 
-  - ${{ parameters.afterBuild }}
+    - ${{ parameters.afterBuild }}
 
-  - ${{ if eq(parameters.agentOs, 'Windows') }}:
-    - powershell: eng\scripts\KillProcesses.ps1
-      displayName: Kill processes
-      continueOnError: true
-      condition: always()
-  - ${{ if ne(parameters.agentOs, 'Windows') }}:
-    - script: eng/scripts/KillProcesses.sh
-      displayName: Kill processes
-      continueOnError: true
-      condition: always()
+    - ${{ if and(eq(parameters.agentOs, 'Windows'), eq(parameters.isTestingJob, true)) }}:
+      - powershell: ./eng/scripts/FinishDumpCollectionForHangingBuilds.ps1 artifacts/log/
+        displayName: Finish background dump collection
+        continueOnError: true
+        condition: always()
 
-  - ${{ each artifact in parameters.artifacts }}:
-    - task: PublishBuildArtifacts@1
-      displayName: Upload artifacts from ${{ artifact.path }}
-      condition: and(or(succeeded(), eq('${{ artifact.publishOnError }}', 'true')), or(eq(variables['system.pullrequest.isfork'], false), eq('${{ artifact.includeForks }}', 'true')))
-      continueOnError: true
-      inputs:
-        ${{ if eq(parameters.buildDirectory, '') }}:
-          pathtoPublish: ${{ artifact.path }}
-        ${{ if ne(parameters.buildDirectory, '') }}:
-          pathtoPublish: ${{ parameters.buildDirectory }}\${{ artifact.path }}
-        ${{ if eq(artifact.name, '') }}:
-          artifactName: artifacts-$(AgentOsName)-$(BuildConfiguration)
-        ${{ if ne(artifact.name, '') }}:
-          artifactName: ${{ artifact.name }}
-        artifactType: Container
-        parallel: true
+    - ${{ if eq(parameters.agentOs, 'Windows') }}:
+      - powershell: eng\scripts\KillProcesses.ps1
+        displayName: Kill processes
+        continueOnError: true
+        condition: always()
+    - ${{ if ne(parameters.agentOs, 'Windows') }}:
+      - script: eng/scripts/KillProcesses.sh
+        displayName: Kill processes
+        continueOnError: true
+        condition: always()
 
-  - ${{ if eq(parameters.isTestingJob, true) }}:
-    - task: PublishTestResults@2
-      displayName: Publish test results
-      condition: always()
-      continueOnError: true
-      inputs:
-        testRunTitle: $(AgentOsName)-$(BuildConfiguration)
-        testRunner: vstest
-        testResultsFiles: '**/artifacts/**/*.trx'
-        mergeTestResults: true
-        buildConfiguration: $(BuildConfiguration)
-        buildPlatform: $(AgentOsName)
-    - task: PublishTestResults@2
-      displayName: Publish test results
-      condition: always()
-      continueOnError: true
-      inputs:
-        testRunTitle: $(AgentOsName)-$(BuildConfiguration)
-        testRunner: xunit
-        testResultsFiles: '**/artifacts/TestResults/**/*.xml'
-        mergeTestResults: true
-        buildConfiguration: $(BuildConfiguration)
-        buildPlatform: $(AgentOsName)
-    - task: PublishTestResults@2
-      displayName: Publish js test results
-      condition: always()
-      inputs:
-        testRunner: junit
-        testResultsFiles: '**/artifacts/log/**/*.junit.xml'
-        buildConfiguration: $(BuildConfiguration)
-        buildPlatform: $(AgentOsName)
-    - task: PublishTestResults@2
-      displayName: Publish Java test results
-      condition: always()
-      inputs:
-        testRunner: junit
-        testResultsFiles: '**/TEST-com.microsoft.signalr*.xml'
-        buildConfiguration: $(BuildConfiguration)
-        buildPlatform: $(AgentOsName)
+    - ${{ each artifact in parameters.artifacts }}:
+      - task: PublishBuildArtifacts@1
+        displayName: Upload artifacts from ${{ artifact.path }}
+        condition: and(or(succeeded(), eq('${{ artifact.publishOnError }}', 'true')), or(eq(variables['system.pullrequest.isfork'], false), eq('${{ artifact.includeForks }}', 'true')))
+        continueOnError: true
+        inputs:
+          ${{ if eq(parameters.buildDirectory, '') }}:
+            pathtoPublish: ${{ artifact.path }}
+          ${{ if ne(parameters.buildDirectory, '') }}:
+            pathtoPublish: ${{ parameters.buildDirectory }}\${{ artifact.path }}
+          ${{ if eq(artifact.name, '') }}:
+            artifactName: artifacts-$(AgentOsName)-$(BuildConfiguration)
+          ${{ if ne(artifact.name, '') }}:
+            artifactName: ${{ artifact.name }}
+          artifactType: Container
+          parallel: true
 
-
-  - ${{ if and(eq(variables['System.TeamProject'], 'internal'), eq(parameters.agentOs, 'Windows')) }}:
-    - task: MicroBuildCleanup@1
-      displayName: Cleanup MicroBuild tasks
-      condition: always()
+    - ${{ if eq(parameters.isTestingJob, true) }}:
+      - task: PublishTestResults@2
+        displayName: Publish VSTest test results
+        condition: always()
+        continueOnError: true
+        inputs:
+          testRunTitle: $(AgentOsName)-$(BuildConfiguration)
+          testRunner: vstest
+          testResultsFiles: '**/artifacts/**/*.trx'
+          mergeTestResults: true
+          buildConfiguration: $(BuildConfiguration)
+          buildPlatform: $(AgentOsName)
+      - task: PublishTestResults@2
+        displayName: Publish js test results
+        condition: always()
+        inputs:
+          testRunner: junit
+          testResultsFiles: '**/artifacts/log/**/*.junit.xml'
+          buildConfiguration: $(BuildConfiguration)
+          buildPlatform: $(AgentOsName)
+      - task: PublishTestResults@2
+        displayName: Publish Java test results
+        condition: always()
+        inputs:
+          testRunner: junit
+          testResultsFiles: '**/TEST-com.microsoft.signalr*.xml'
+          buildConfiguration: $(BuildConfiguration)
+          buildPlatform: $(AgentOsName)

+ 10 - 1
Directory.Build.props

@@ -21,6 +21,15 @@
     <IsSampleProject Condition="$(RepoRelativeProjectDir.Contains('sample'))">true</IsSampleProject>
     <IsAnalyzersProject Condition="$(MSBuildProjectName.EndsWith('.Analyzers'))">true</IsAnalyzersProject>
     <IsShipping Condition="'$(IsSampleProject)' == 'true' or '$(IsTestAssetProject)' == 'true' or '$(IsBenchmarkProject)' == 'true' or '$(IsUnitTestProject)' == 'true'">false</IsShipping>
+
+    <!--
+      Following logic mimics core-setup approach as well as
+      https://github.com/dotnet/arcade/blob/694d59f090b743f894779d04a7ffe11cbaf352e7/src/Microsoft.DotNet.Arcade.Sdk/tools/Publish.proj#L30-L31
+      $(DotNetFinalVersionKind) is set globally when doing final aka stable builds. Arcade infrastructure should pick
+      up $(IsStableBuild) automatically; property is also used to control prerelease branding.
+    -->
+    <IsStableBuild>false</IsStableBuild>
+    <IsStableBuild Condition=" '$(DotNetFinalVersionKind)' == 'release' ">true</IsStableBuild>
   </PropertyGroup>
 
   <Import Project="eng\FlakyTests.BeforeArcade.props" />
@@ -119,7 +128,7 @@
     <BuildProjectReferences Condition=" '$(NoBuild)' == 'true' ">false</BuildProjectReferences>
   </PropertyGroup>
 
-  <!-- Artifacts layout -->
+  <!-- Artifacts layout. Keep these values consistent with items defined in eng/Publishing.props. -->
   <PropertyGroup>
     <InstallersOutputPath>$(ArtifactsDir)installers\$(Configuration)\</InstallersOutputPath>
     <SymbolsOutputPath>$(ArtifactsDir)symbols\$(Configuration)\</SymbolsOutputPath>

+ 2 - 9
Directory.Build.targets

@@ -4,12 +4,6 @@
     <!-- When OnlyPackPlatformSpecificPackages is set, only produce packages for projects which set RuntimeIdentifier. -->
     <IsPackable Condition=" '$(OnlyPackPlatformSpecificPackages)' == 'true' AND '$(IsPackable)' != 'false' AND '$(RuntimeIdentifier)' == '' ">false</IsPackable>
 
-    <!--
-      By default, all projects which produce packages are not intended to ship to NuGet.org as a product package.
-      Packages which are intended to ship to NuGet.org must opt-in by setting this to true in the project file.
-    -->
-    <IsShippingPackage Condition=" '$(IsShippingPackage)' == '' ">false</IsShippingPackage>
-
     <!--
       By default, assemblies which are only in the Microsoft.AspNetCore.App shared framework are not available as NuGet packages.
     -->
@@ -34,10 +28,9 @@
     <PackageBrandingVersion>$(VersionPrefix)</PackageBrandingVersion>
     <PackageBrandingVersion Condition=" '$(VersionSuffix)' != '' ">$(PackageBrandingVersion) $(BrandingVersionSuffix.Trim())</PackageBrandingVersion>
 
-    <SiteExtensionSuffix>$(VersionSuffix.Replace('.','-'))</SiteExtensionSuffix>
-    <SiteExtensionPackageVersion>$(VersionPrefix)-$(SiteExtensionSuffix)</SiteExtensionPackageVersion>
+    <SiteExtensionSuffix>$(VersionPrefix)</SiteExtensionSuffix>
+    <SiteExtensionPackageVersion Condition=" '$(VersionSuffix)' != '' ">$(VersionPrefix)-$(VersionSuffix.Replace('.','-'))</SiteExtensionPackageVersion>
 
-    <OriginalPackageVersion>$(Version)</OriginalPackageVersion>
     <PackageVersion Condition=" '$(PackageVersion)' == '' ">$(Version)</PackageVersion>
     <PackageVersion Condition=" '$(NoSemVer20)' == 'true' ">$(SiteExtensionPackageVersion)</PackageVersion>
     <SharedFxVersion>$(PackageVersion)</SharedFxVersion>

+ 5 - 1
build.sh

@@ -221,7 +221,7 @@ if [ "$build_deps" = false ]; then
     msbuild_args[${#msbuild_args[*]}]="-p:BuildProjectReferences=false"
 fi
 
-if [ "$build_managed" = true ] || (["$build_all" = true ] && [ "$build_managed" != false ]); then
+if [ "$build_managed" = true ] || ([ "$build_all" = true ] && [ "$build_managed" != false ]); then
     if [ -z "$build_nodejs" ]; then
         if [ -x "$(command -v node)" ]; then
             __warn "Building of C# project is enabled and has dependencies on NodeJS projects. Building of NodeJS projects is enabled since node is detected on PATH."
@@ -266,6 +266,10 @@ if [ -z "$configuration" ]; then
 fi
 msbuild_args[${#msbuild_args[*]}]="-p:Configuration=$configuration"
 
+# Set verbosity
+echo "Setting msbuild verbosity to $verbosity"
+msbuild_args[${#msbuild_args[*]}]="-verbosity:$verbosity"
+
 # Initialize global variables need to be set before the import of Arcade is imported
 restore=$run_restore
 

+ 2 - 1
dockerbuild.sh

@@ -124,6 +124,7 @@ docker build "$(dirname "$dockerfile")" \
     --build-arg "USER=$(whoami)" \
     --build-arg "USER_ID=$(id -u)" \
     --build-arg "GROUP_ID=$(id -g)" \
+    --build-arg "WORKDIR=$DIR" \
     --tag $tagname \
     -f "$dockerfile"
 
@@ -138,7 +139,7 @@ docker run \
     -e BUILD_SOURCEBRANCH \
     -e DOTNET_CLI_TELEMETRY_OPTOUT \
     -e Configuration \
-    -v "$DIR:/code/build" \
+    -v "$DIR:$DIR" \
     ${docker_args[@]+"${docker_args[@]}"} \
     $tagname \
     ./build.sh \

+ 24 - 10
docs/Artifacts.md

@@ -3,22 +3,36 @@ Artifacts
 
 Building this repo produces build artifacts in the directory structure described below. Build outputs are organized into logical groups based on artifact type and the intended usage of the artifacts.
 
+See also https://github.com/dotnet/arcade/blob/master/Documentation/ArcadeSdk.md This repo follows _most_ of the conventions described there.
+
 ```
 artifacts/
   installers/
     $(Configuration)/
-        *.msi            = Windows installers
-        *.deb, *.rpm     = Linux installers
-        *.zip, *.tar.gz  = archives versions of installers
+      *.msi            = Windows installers
+      *.deb, *.rpm     = Linux installers
+      *.zip, *.tar.gz  = archives versions of installers
+  log/
+    runningProcesses*.txt = Process list from just before build completed
+    runningProcesses*.bak = Process list from two minutes before runningProcesses*.txt files were written
+    *.binlog           = Binary logs for a few build phases e.g. site extension build
+    **/
+      *.log            = Log files for test runs and individual tests
+    $(Configuration)/
+      *.binlog         = Binary logs for most build phases
   packages/
     $(Configuration)/
-        Shipping/        = Packages which are intended for use by customers. These, along with installers, represent the 'product'.
-            *.nupkg      = NuGet packages which ship to nuget.org
-            *.jar        = Java packages which ship to Maven Central and others
-            *.tgz        = NPM packages which ship to npmjs.org
-        NonShipping/
-            *.nupkg      = NuGet packages for internal use only. Used to hand off bits to Microsoft partner teams. Not intended for use by customers.
+      Shipping/        = Packages which are intended for use by customers. These, along with installers, represent the 'product'.
+        *.nupkg        = NuGet packages which ship to nuget.org
+        *.jar          = Java packages which ship to Maven Central and others
+        *.tgz          = NPM packages which ship to npmjs.org
+      NonShipping/
+        *.nupkg        = NuGet packages for internal use only. Used to hand off bits to Microsoft partner teams. Not intended for use by customers.
+  symbols/
+    $(Configuration)/
+      $(TargetFramework)/
+        *.pdb          = Loose symbol files for symbol server publication. Special cases where *.symbols.nupkg packaging is cumbersome.
   VSSetup/
     $(Configuration)/
-        *.vsix           = Visual Studio extensions
+      *.vsix           = Visual Studio extensions. None currently exist.
 ```

+ 0 - 11
eng/AfterSolutionBuild.targets

@@ -17,15 +17,4 @@
       SharedFrameworkTargetFramework="netcoreapp$(AspNetCoreMajorVersion).$(AspNetCoreMinorVersion)" />
   </Target>
 
-  <Target Name="GenerateBuildAssetManifest" AfterTargets="Pack" Condition="'$(ContinuousIntegrationBuild)' == 'true' and '$(DotNetBuildFromSource)' != 'true'">
-    <!-- Generate build manifests. These manifests are used by Maestro and the Build Asset Registry to flow dependencies to other repos. -->
-    <MSBuild Projects="$(MSBuildThisFileDirectory)tools\Maestro\Maestro.csproj"
-          Targets="Restore"
-          Properties="__DummyTarget=Restore" />
-
-    <MSBuild Projects="$(MSBuildThisFileDirectory)tools\Maestro\Maestro.csproj"
-             Targets="GenerateBuildAssetManifest"
-             Properties="__DummyTarget=GenerateBuildAssetManifest" />
-  </Target>
-
 </Project>

+ 1 - 0
eng/Build.props

@@ -42,6 +42,7 @@
 
     <!-- Exclude the benchmarks because they use <PackageReference>. -->
     <ProjectToExclude Include="
+                      $(RepoRoot)src\Components\benchmarkapps\**\*.csproj;
                       $(RepoRoot)src\Mvc\benchmarkapps\**\*.csproj;
                       $(RepoRoot)src\Servers\Kestrel\perf\PlatformBenchmarks\**\*.csproj;
                       $(RepoRoot)src\SignalR\perf\benchmarkapps\**\*.csproj;

+ 1 - 1
eng/CodeGen.proj

@@ -85,4 +85,4 @@
           SkipNonexistentProjects="true" />
   </Target>
 
-</Project>
+</Project>

+ 2 - 0
eng/Dependencies.props

@@ -172,6 +172,8 @@ and are generated based on the last package release.
     <LatestPackageReference Include="MessagePack" Version="$(MessagePackPackageVersion)" />
     <LatestPackageReference Include="Microsoft.Azure.KeyVault" Version="$(MicrosoftAzureKeyVaultPackageVersion)" />
     <LatestPackageReference Include="Microsoft.Azure.Storage.Blob" Version="$(MicrosoftAzureStorageBlobPackageVersion)" />
+    <LatestPackageReference Include="Microsoft.Data.OData" Version="$(MicrosoftDataODataPackageVersion)" />
+    <LatestPackageReference Include="Microsoft.Data.Services.Client" Version="$(MicrosoftDataServicesClientPackageVersion)" />
     <LatestPackageReference Include="Mono.Cecil" Version="$(MonoCecilPackageVersion)" />
     <LatestPackageReference Include="Mono.WebAssembly.Interop" Version="$(MonoWebAssemblyInteropPackageVersion)" />
     <LatestPackageReference Include="Moq" Version="$(MoqPackageVersion)" />

+ 2 - 0
eng/PatchConfig.props

@@ -65,7 +65,9 @@ Later on, this will be checked using this condition:
   </PropertyGroup>
   <PropertyGroup Condition=" '$(VersionPrefix)' == '2.2.7' ">
     <PackagesInPatch>
+      Microsoft.AspNetCore.DataProtection.AzureStorage;
       Microsoft.AspNetCore.Hosting;
+      Microsoft.AspNetCore.SpaServices;
     </PackagesInPatch>
   </PropertyGroup>
 </Project>

+ 2 - 0
eng/ProjectReferences.props

@@ -15,6 +15,8 @@
     <ProjectReferenceProvider Include="GetDocument.Insider" ProjectPath="$(RepoRoot)src\Tools\GetDocumentInsider\src\GetDocumentInsider.csproj"  />
     <ProjectReferenceProvider Include="Microsoft.AspNetCore.SignalR.Specification.Tests" ProjectPath="$(RepoRoot)src\SignalR\server\Specification.Tests\src\Microsoft.AspNetCore.SignalR.Specification.Tests.csproj"  />
     <ProjectReferenceProvider Include="Microsoft.AspNetCore.Blazor.Build" ProjectPath="$(RepoRoot)src\Components\Blazor\Build\src\Microsoft.AspNetCore.Blazor.Build.csproj"  />
+    <ProjectReferenceProvider Include="Ignitor" ProjectPath="$(RepoRoot)src\Components\Ignitor\src\Ignitor.csproj"  />
+    <ProjectReferenceProvider Include="BlazorServerApp" ProjectPath="$(RepoRoot)src\Components\Samples\BlazorServerApp\BlazorServerApp.csproj"  />
     <ProjectReferenceProvider Include="Microsoft.AspNetCore" ProjectPath="$(RepoRoot)src\DefaultBuilder\src\Microsoft.AspNetCore.csproj" RefProjectPath="$(RepoRoot)src\DefaultBuilder\ref\Microsoft.AspNetCore.csproj" />
     <ProjectReferenceProvider Include="Microsoft.AspNetCore.JsonPatch" ProjectPath="$(RepoRoot)src\Features\JsonPatch\src\Microsoft.AspNetCore.JsonPatch.csproj" RefProjectPath="$(RepoRoot)src\Features\JsonPatch\ref\Microsoft.AspNetCore.JsonPatch.csproj" />
     <ProjectReferenceProvider Include="Microsoft.AspNetCore.DataProtection.Abstractions" ProjectPath="$(RepoRoot)src\DataProtection\Abstractions\src\Microsoft.AspNetCore.DataProtection.Abstractions.csproj" RefProjectPath="$(RepoRoot)src\DataProtection\Abstractions\ref\Microsoft.AspNetCore.DataProtection.Abstractions.csproj" />

+ 56 - 0
eng/Publishing.props

@@ -0,0 +1,56 @@
+<Project>
+  <PropertyGroup Condition=" HasTrailingSlash('$(ArtifactsDir)') ">
+    <!-- The one use of ArtifactsDir in Publish.proj adds an additional slash, confusing itself. -->
+    <ArtifactsDir>$(ArtifactsDir.Substring(0, $([MSBuild]::Subtract($(ArtifactsDir.Length), 1))))</ArtifactsDir>
+
+    <PublishDependsOnTargets>$(PublishDependsOnTargets);_PublishInstallers</PublishDependsOnTargets>
+
+    <_UploadPathRoot>aspnetcore</_UploadPathRoot>
+  </PropertyGroup>
+
+  <!-- $(InstallersOutputPath) and $(SymbolsOutputPath) are not defined. Root Directory.Build.props is not imported. -->
+  <ItemGroup>
+    <!-- Include our "loose" PDBs when publishing symbols. -->
+    <FilesToPublishToSymbolServer Include="$(ArtifactsDir)\symbols\**\*.pdb" />
+
+    <!-- Prepare for _PublishInstallers target. -->
+    <_InstallersToPublish Remove="@(_InstallersToPublish)" />
+    <_InstallersToPublish Include="$(ArtifactsDir)\packages\**\*.jar" UploadPathSegment="jar" />
+    <_InstallersToPublish Include="$(ArtifactsDir)\packages\**\*.pom" UploadPathSegment="jar" />
+    <_InstallersToPublish Include="$(ArtifactsDir)\packages\**\*.tgz" UploadPathSegment="npm" />
+    <_InstallersToPublish Include="$(ArtifactsDir)\installers\**\*.deb" UploadPathSegment="Runtime" />
+    <_InstallersToPublish Include="$(ArtifactsDir)\installers\**\*.exe" UploadPathSegment="Runtime" />
+    <_InstallersToPublish Include="$(ArtifactsDir)\installers\**\*.msi" UploadPathSegment="Runtime" />
+    <_InstallersToPublish Include="$(ArtifactsDir)\installers\**\*.rpm" UploadPathSegment="Runtime" />
+    <_InstallersToPublish Include="$(ArtifactsDir)\installers\**\*.tar.gz" UploadPathSegment="Runtime" />
+    <_InstallersToPublish Include="$(ArtifactsDir)\installers\**\*.version" UploadPathSegment="Runtime"
+        Condition=" '$(PublishInstallerBaseVersion)' == 'true' " />
+    <_InstallersToPublish Include="$(ArtifactsDir)\installers\**\*.wixlib" UploadPathSegment="Runtime" />
+    <_InstallersToPublish Include="$(ArtifactsDir)\installers\**\*.zip" UploadPathSegment="Runtime" />
+  </ItemGroup>
+
+  <Target Name="_PublishInstallers">
+    <!-- This target is defined in eng/targets/Packaging.targets and included in every C# and F# project. -->
+    <MSBuild Projects="$(RepoRoot)src\Mvc\Mvc\src\Microsoft.AspNetCore.Mvc.csproj"
+        Targets="_GetPackageVersionInfo"
+        SkipNonexistentProjects="false">
+      <Output TaskParameter="TargetOutputs" ItemName="_ResolvedPackageVersionInfo" />
+    </MSBuild>
+
+    <PropertyGroup>
+      <_PackageVersion>@(_ResolvedPackageVersionInfo->'%(PackageVersion)')</_PackageVersion>
+    </PropertyGroup>
+
+    <ItemGroup>
+      <!-- Do not push .nupkg files from Linux and macOS builds. They'll be packed up separately and signed on Windows. -->
+      <ItemsToPushToBlobFeed Remove="@(ItemsToPushToBlobFeed)" Condition="'$(OS)' != 'Windows_NT'" />
+
+      <ItemsToPushToBlobFeed Include="@(_InstallersToPublish)">
+        <IsShipping>true</IsShipping>
+        <ManifestArtifactData>ShipInstaller=dotnetcli</ManifestArtifactData>
+        <PublishFlatContainer>true</PublishFlatContainer>
+        <RelativeBlobPath>$(_UploadPathRoot)/%(_InstallersToPublish.UploadPathSegment)/$(_PackageVersion)/%(Filename)%(Extension)</RelativeBlobPath>
+      </ItemsToPushToBlobFeed>
+    </ItemGroup>
+  </Target>
+</Project>

+ 4 - 0
eng/SignCheckExclusionsFile.txt

@@ -0,0 +1,4 @@
+apphost.exe;; Exclude the apphost because this is expected to be code-signed by customers after the SDK modifies it.
+.js;; We do not sign JavaScript files.
+.binlog;; MSBuild binary logs are not signed though they are sometimes placed where validation thinks they should be.
+WixUIWixca|WixDepCA;; We do not sign WiX content in our installers.

+ 1 - 0
eng/Signing.props

@@ -21,6 +21,7 @@
     -->
     <FileExtensionSignInfo Include=".jar" CertificateName="MicrosoftJARSHA2" />
     <FileExtensionSignInfo Include=".ps1;.psd1;.psm1;.psc1" CertificateName="Microsoft400" />
+    <FileExtensionSignInfo Include=".dll;.exe" CertificateName="Microsoft400" />
     <FileExtensionSignInfo Include=".nupkg" CertificateName="NuGet" />
     <FileExtensionSignInfo Include=".vsix" CertificateName="VsixSHA2" />
     <FileExtensionSignInfo Include=".zip" CertificateName="None" />

+ 6 - 6
eng/Version.Details.xml

@@ -412,17 +412,17 @@
       <Uri>https://github.com/aspnet/Extensions</Uri>
       <Sha>d15c5687db29e4e1f31a302fe243226b0a3a17e3</Sha>
     </Dependency>
-    <Dependency Name="Microsoft.DotNet.GenAPI" Version="1.0.0-beta.19425.1">
+    <Dependency Name="Microsoft.DotNet.GenAPI" Version="1.0.0-beta.19462.4">
       <Uri>https://github.com/dotnet/arcade</Uri>
-      <Sha>2de3acc671fc624191672a45564f9ef130af5cd4</Sha>
+      <Sha>f8546fbab59a74a66c83b8cb76b3f6877ce1d374</Sha>
     </Dependency>
-    <Dependency Name="Microsoft.DotNet.Arcade.Sdk" Version="1.0.0-beta.19425.1">
+    <Dependency Name="Microsoft.DotNet.Arcade.Sdk" Version="1.0.0-beta.19462.4">
       <Uri>https://github.com/dotnet/arcade</Uri>
-      <Sha>2de3acc671fc624191672a45564f9ef130af5cd4</Sha>
+      <Sha>f8546fbab59a74a66c83b8cb76b3f6877ce1d374</Sha>
     </Dependency>
-    <Dependency Name="Microsoft.DotNet.Helix.Sdk" Version="2.0.0-beta.19425.1">
+    <Dependency Name="Microsoft.DotNet.Helix.Sdk" Version="2.0.0-beta.19462.4">
       <Uri>https://github.com/dotnet/arcade</Uri>
-      <Sha>2de3acc671fc624191672a45564f9ef130af5cd4</Sha>
+      <Sha>f8546fbab59a74a66c83b8cb76b3f6877ce1d374</Sha>
     </Dependency>
     <Dependency Name="Microsoft.AspNetCore.Testing" Version="5.0.0-alpha1.19467.2" CoherentParentDependency="Microsoft.EntityFrameworkCore">
       <Uri>https://github.com/aspnet/Extensions</Uri>

+ 16 - 9
eng/Versions.props

@@ -10,6 +10,11 @@
     <AspNetCoreMinorVersion>0</AspNetCoreMinorVersion>
     <AspNetCorePatchVersion>0</AspNetCorePatchVersion>
     <PreReleasePreviewNumber>1</PreReleasePreviewNumber>
+    <!--
+        When StabilizePackageVersion is set to 'true', this branch will produce stable outputs for 'Shipping' packages
+    -->
+    <StabilizePackageVersion Condition="'$(StabilizePackageVersion)' == ''">false</StabilizePackageVersion>
+    <DotNetFinalVersionKind Condition="'$(StabilizePackageVersion)' == 'true'">release</DotNetFinalVersionKind>
     <PreReleaseVersionLabel>alpha$(PreReleasePreviewNumber)</PreReleaseVersionLabel>
     <PreReleaseBrandingLabel>Alpha $(PreReleasePreviewNumber)</PreReleaseBrandingLabel>
     <AspNetCoreMajorMinorVersion>$(AspNetCoreMajorVersion).$(AspNetCoreMinorVersion)</AspNetCoreMajorMinorVersion>
@@ -50,7 +55,7 @@
   -->
   <PropertyGroup Label="Automated">
     <!-- Packages from dotnet/arcade -->
-    <MicrosoftDotNetGenAPIPackageVersion>1.0.0-beta.19425.1</MicrosoftDotNetGenAPIPackageVersion>
+    <MicrosoftDotNetGenAPIPackageVersion>1.0.0-beta.19462.4</MicrosoftDotNetGenAPIPackageVersion>
     <!-- Packages from dotnet/roslyn -->
     <MicrosoftNetCompilersToolsetPackageVersion>3.4.0-beta1-19456-03</MicrosoftNetCompilersToolsetPackageVersion>
     <!-- Packages from dotnet/core-setup -->
@@ -202,6 +207,8 @@
     <MicrosoftCodeAnalysisCommonPackageVersion>3.0.0</MicrosoftCodeAnalysisCommonPackageVersion>
     <MicrosoftCodeAnalysisCSharpPackageVersion>3.0.0</MicrosoftCodeAnalysisCSharpPackageVersion>
     <MicrosoftCodeAnalysisCSharpWorkspacesPackageVersion>3.0.0</MicrosoftCodeAnalysisCSharpWorkspacesPackageVersion>
+    <MicrosoftDataODataPackageVersion>5.8.4</MicrosoftDataODataPackageVersion>
+    <MicrosoftDataServicesClientPackageVersion>5.8.4</MicrosoftDataServicesClientPackageVersion>
     <MicrosoftIdentityModelClientsActiveDirectoryPackageVersion>3.19.8</MicrosoftIdentityModelClientsActiveDirectoryPackageVersion>
     <MicrosoftIdentityModelLoggingPackageVersion>5.5.0</MicrosoftIdentityModelLoggingPackageVersion>
     <MicrosoftIdentityModelProtocolsOpenIdConnectPackageVersion>5.5.0</MicrosoftIdentityModelProtocolsOpenIdConnectPackageVersion>
@@ -222,17 +229,17 @@
     <CastleCorePackageVersion>4.2.1</CastleCorePackageVersion>
     <FSharpCorePackageVersion>4.2.1</FSharpCorePackageVersion>
     <GoogleProtobufPackageVersion>3.8.0</GoogleProtobufPackageVersion>
-    <GrpcAspNetCorePackageVersion>0.2.23-pre1</GrpcAspNetCorePackageVersion>
-    <IdentityServer4AspNetIdentityPackageVersion>3.0.0-preview7.33</IdentityServer4AspNetIdentityPackageVersion>
-    <IdentityServer4EntityFrameworkPackageVersion>3.0.0-preview7.33</IdentityServer4EntityFrameworkPackageVersion>
-    <IdentityServer4PackageVersion>3.0.0-preview7.33</IdentityServer4PackageVersion>
-    <IdentityServer4StoragePackageVersion>3.0.0-preview7.33</IdentityServer4StoragePackageVersion>
-    <IdentityServer4EntityFrameworkStoragePackageVersion>3.0.0-preview7.33</IdentityServer4EntityFrameworkStoragePackageVersion>
+    <GrpcAspNetCorePackageVersion>2.23.1</GrpcAspNetCorePackageVersion>
+    <IdentityServer4AspNetIdentityPackageVersion>3.0.0</IdentityServer4AspNetIdentityPackageVersion>
+    <IdentityServer4EntityFrameworkPackageVersion>3.0.0</IdentityServer4EntityFrameworkPackageVersion>
+    <IdentityServer4PackageVersion>3.0.0</IdentityServer4PackageVersion>
+    <IdentityServer4StoragePackageVersion>3.0.0</IdentityServer4StoragePackageVersion>
+    <IdentityServer4EntityFrameworkStoragePackageVersion>3.0.0</IdentityServer4EntityFrameworkStoragePackageVersion>
     <MessagePackPackageVersion>1.7.3.7</MessagePackPackageVersion>
     <MoqPackageVersion>4.10.0</MoqPackageVersion>
     <MonoCecilPackageVersion>0.10.1</MonoCecilPackageVersion>
     <NewtonsoftJsonBsonPackageVersion>1.0.2</NewtonsoftJsonBsonPackageVersion>
-    <NewtonsoftJsonPackageVersion>12.0.1</NewtonsoftJsonPackageVersion>
+    <NewtonsoftJsonPackageVersion>12.0.2</NewtonsoftJsonPackageVersion>
     <NSwagApiDescriptionClientPackageVersion>13.0.4</NSwagApiDescriptionClientPackageVersion>
     <SeleniumSupportPackageVersion>3.12.1</SeleniumSupportPackageVersion>
     <SeleniumWebDriverMicrosoftDriverPackageVersion>17.17134.0</SeleniumWebDriverMicrosoftDriverPackageVersion>
@@ -248,7 +255,7 @@
     <XunitAssertPackageVersion>$(XunitVersion)</XunitAssertPackageVersion>
     <XunitExtensibilityCorePackageVersion>$(XunitVersion)</XunitExtensibilityCorePackageVersion>
     <XunitExtensibilityExecutionPackageVersion>$(XunitVersion)</XunitExtensibilityExecutionPackageVersion>
-    <MicrosoftDataSqlClientPackageVersion>1.0.19189.1-Preview</MicrosoftDataSqlClientPackageVersion>
+    <MicrosoftDataSqlClientPackageVersion>1.0.19249.1</MicrosoftDataSqlClientPackageVersion>
   </PropertyGroup>
   <!-- Restore feeds -->
   <PropertyGroup Label="Restore feeds">

+ 5 - 0
eng/Workarounds.props

@@ -18,6 +18,11 @@
     <TestRunnerAdditionalArguments>$(TestRunnerAdditionalArguments) -nocolor</TestRunnerAdditionalArguments>
   </PropertyGroup>
 
+  <PropertyGroup>
+    <!-- Working around https://github.com/NuGet/Home/issues/8467 -->
+    <NoWarn>$(NoWarn);NU5131</NoWarn>
+  </PropertyGroup>
+
   <!-- Workaround https://github.com/dotnet/roslyn/issues/27975 -->
   <PropertyGroup>
     <!-- We use the compiler toolset that comes from NuGet Packages rather than the SDK built-in.

+ 15 - 0
eng/Workarounds.targets

@@ -1,5 +1,20 @@
 <!-- Use this file to workaround issues. List the issue tracking the item to fix so we can remove the workaround when the issue is resolved. -->
 <Project>
+  <!-- Workaround while there is no 5.0 SDK available, suppress unsupported version error -->
+  <PropertyGroup>
+    <NETCoreAppMaximumVersion>5.0</NETCoreAppMaximumVersion>
+  </PropertyGroup>
+
+  <ItemGroup>
+    <!-- Reference base shared framework at incoming dependency flow version, not bundled sdk version. -->
+    <FrameworkReference
+      Update="Microsoft.NETCore.App"
+      Condition="'$(TargetFramework)' == '$(DefaultNetCoreTargetFramework)'"
+      RuntimeFrameworkVersion="$(MicrosoftNETCoreAppRuntimeVersion)"
+      TargetingPackVersion="$(MicrosoftNETCoreAppRefPackageVersion)"
+      />
+  </ItemGroup>
+
   <!--
     Workaround https://github.com/aspnet/AspNetCore/issues/4257.
     The web sdk adds an implicit framework reference. This removes it until we can update our build to use framework references.

+ 4 - 0
eng/common/build.ps1

@@ -85,6 +85,10 @@ function Build {
     # Re-assign properties to a new variable because PowerShell doesn't let us append properties directly for unclear reasons.
     # Explicitly set the type as string[] because otherwise PowerShell would make this char[] if $properties is empty.
     [string[]] $msbuildArgs = $properties
+    
+    # Resolve relative project paths into full paths 
+    $projects = ($projects.Split(';').ForEach({Resolve-Path $_}) -join ';')
+    
     $msbuildArgs += "/p:Projects=$projects"
     $properties = $msbuildArgs
   }

+ 4 - 4
eng/common/performance/perfhelixpublish.proj

@@ -83,8 +83,8 @@
   <ItemGroup Condition="$(TargetCsproj.Contains('MicroBenchmarks.csproj'))">
     <HelixWorkItem Include="@(Partition)">
       <PayloadDirectory>$(WorkItemDirectory)</PayloadDirectory>
-      <PreCommands Condition="'$(Compare)' == 'true'">$(WorkItemCommand) --bdn-arguments="--anyCategories $(BDNCategories) $(ExtraBenchmarkDotNetArguments) $(BaselineCoreRunArgument) --artifacts $(BaselineArtifactsDirectory) --partition-count $(PartitionCount) --partition-index %(HelixWorkItem.Index)"</PreCommands>
-      <Command>$(WorkItemCommand) --bdn-arguments="--anyCategories $(BDNCategories) $(ExtraBenchmarkDotNetArguments) $(CoreRunArgument) --artifacts $(ArtifactsDirectory) --partition-count $(PartitionCount) --partition-index %(HelixWorkItem.Index)"</Command>
+      <PreCommands Condition="'$(Compare)' == 'true'">$(WorkItemCommand) --bdn-artifacts $(BaselineArtifactsDirectory) --bdn-arguments="--anyCategories $(BDNCategories) $(ExtraBenchmarkDotNetArguments) $(BaselineCoreRunArgument) --partition-count $(PartitionCount) --partition-index %(HelixWorkItem.Index)"</PreCommands>
+      <Command>$(WorkItemCommand) --bdn-artifacts $(ArtifactsDirectory) --bdn-arguments="--anyCategories $(BDNCategories) $(ExtraBenchmarkDotNetArguments) $(CoreRunArgument) --partition-count $(PartitionCount) --partition-index %(HelixWorkItem.Index)"</Command>
       <PostCommands Condition="'$(Compare)' == 'true'">$(DotnetExe) run -f $(_Framework) -p $(ResultsComparer) --base $(BaselineArtifactsDirectory) --diff $(ArtifactsDirectory) --threshold 2$(Percent) --xml $(XMLResults);$(FinalCommand)</PostCommands>
       <Timeout>4:00</Timeout>
     </HelixWorkItem>
@@ -93,8 +93,8 @@
   <ItemGroup Condition="!$(TargetCsproj.Contains('MicroBenchmarks.csproj'))">
     <HelixWorkItem Include="$(BuildConfig).WorkItem">
       <PayloadDirectory>$(WorkItemDirectory)</PayloadDirectory>
-      <PreCommands Condition="'$(Compare)' == 'true'">$(WorkItemCommand) --bdn-arguments="--anyCategories $(BDNCategories) $(ExtraBenchmarkDotNetArguments) $(BaselineCoreRunArgument) --artifacts $(ArtifactsDirectory)"</PreCommands>
-      <Command>$(WorkItemCommand) --bdn-arguments="--anyCategories $(BDNCategories) $(ExtraBenchmarkDotNetArguments) $(CoreRunArgument) --artifacts $(ArtifactsDirectory)"</Command>
+      <PreCommands Condition="'$(Compare)' == 'true'">$(WorkItemCommand) --bdn-artifacts $(BaselineArtifactsDirectory) --bdn-arguments="--anyCategories $(BDNCategories) $(ExtraBenchmarkDotNetArguments) $(BaselineCoreRunArgument)"</PreCommands>
+      <Command>$(WorkItemCommand) --bdn-artifacts $(ArtifactsDirectory) --bdn-arguments="--anyCategories $(BDNCategories) $(ExtraBenchmarkDotNetArguments) $(CoreRunArgument)"</Command>
       <PostCommands Condition="'$(Compare)' == 'true'">$(DotnetExe) run -f $(_Framework) -p $(ResultsComparer) --base $(BaselineArtifactsDirectory) --diff $(ArtifactsDirectory) --threshold 2$(Percent) --xml $(XMLResults)</PostCommands>
       <Timeout>4:00</Timeout>
     </HelixWorkItem>

+ 1 - 1
eng/common/performance/performance-setup.ps1

@@ -17,7 +17,7 @@ Param(
     [string] $Configurations="CompilationMode=$CompilationMode"
 )
 
-$RunFromPerformanceRepo = ($Repository -eq "dotnet/performance")
+$RunFromPerformanceRepo = ($Repository -eq "dotnet/performance") -or ($Repository -eq "dotnet-performance")
 $UseCoreRun = ($CoreRootDirectory -ne [string]::Empty)
 $UseBaselineCoreRun = ($BaselineCoreRootDirectory -ne [string]::Empty)
 

+ 1 - 1
eng/common/performance/performance-setup.sh

@@ -113,7 +113,7 @@ while (($# > 0)); do
   esac
 done
 
-if [[ "$repository" == "dotnet/performance" ]]; then
+if [ "$repository" == "dotnet/performance" ] || [ "$repository" == "dotnet-performance" ]; then
     run_from_perf_repo=true
 fi
 

+ 9 - 8
eng/common/sdl/execute-all-sdl-tools.ps1

@@ -45,6 +45,7 @@ if ($GuardianPackageName) {
   $guardianCliLocation = $GuardianCliLocation
 }
 
+$workingDirectory = (Split-Path $SourceDirectory -Parent)
 $ValidPath = Test-Path $guardianCliLocation
 
 if ($ValidPath -eq $False)
@@ -53,13 +54,13 @@ if ($ValidPath -eq $False)
   exit 1
 }
 
-& $(Join-Path $PSScriptRoot "init-sdl.ps1") -GuardianCliLocation $guardianCliLocation -Repository $RepoName -BranchName $BranchName -WorkingDirectory (Split-Path $SourceDirectory -Parent) -AzureDevOpsAccessToken $AzureDevOpsAccessToken -GuardianLoggerLevel $GuardianLoggerLevel
-$gdnFolder = Join-Path (Split-Path $SourceDirectory -Parent) ".gdn"
+& $(Join-Path $PSScriptRoot "init-sdl.ps1") -GuardianCliLocation $guardianCliLocation -Repository $RepoName -BranchName $BranchName -WorkingDirectory $workingDirectory -AzureDevOpsAccessToken $AzureDevOpsAccessToken -GuardianLoggerLevel $GuardianLoggerLevel
+$gdnFolder = Join-Path $workingDirectory ".gdn"
 
 if ($TsaOnboard) {
   if ($TsaCodebaseName -and $TsaNotificationEmail -and $TsaCodebaseAdmin -and $TsaBugAreaPath) {
-    Write-Host "$guardianCliLocation tsa-onboard --codebase-name `"$TsaCodebaseName`" --notification-alias `"$TsaNotificationEmail`" --codebase-admin `"$TsaCodebaseAdmin`" --instance-url `"$TsaInstanceUrl`" --project-name `"$TsaProjectName`" --area-path `"$TsaBugAreaPath`" --iteration-path `"$TsaIterationPath`" --working-directory $ArtifactsDirectory --logger-level $GuardianLoggerLevel"
-    & $guardianCliLocation tsa-onboard --codebase-name "$TsaCodebaseName" --notification-alias "$TsaNotificationEmail" --codebase-admin "$TsaCodebaseAdmin" --instance-url "$TsaInstanceUrl" --project-name "$TsaProjectName" --area-path "$TsaBugAreaPath" --iteration-path "$TsaIterationPath" --working-directory $ArtifactsDirectory --logger-level $GuardianLoggerLevel
+    Write-Host "$guardianCliLocation tsa-onboard --codebase-name `"$TsaCodebaseName`" --notification-alias `"$TsaNotificationEmail`" --codebase-admin `"$TsaCodebaseAdmin`" --instance-url `"$TsaInstanceUrl`" --project-name `"$TsaProjectName`" --area-path `"$TsaBugAreaPath`" --iteration-path `"$TsaIterationPath`" --working-directory $workingDirectory --logger-level $GuardianLoggerLevel"
+    & $guardianCliLocation tsa-onboard --codebase-name "$TsaCodebaseName" --notification-alias "$TsaNotificationEmail" --codebase-admin "$TsaCodebaseAdmin" --instance-url "$TsaInstanceUrl" --project-name "$TsaProjectName" --area-path "$TsaBugAreaPath" --iteration-path "$TsaIterationPath" --working-directory $workingDirectory --logger-level $GuardianLoggerLevel
     if ($LASTEXITCODE -ne 0) {
       Write-Host "Guardian tsa-onboard failed with exit code $LASTEXITCODE."
       exit $LASTEXITCODE
@@ -71,10 +72,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 -CrScanAdditionalRunConfigParams $CrScanAdditionalRunConfigParams -PoliCheckAdditionalRunConfigParams $PoliCheckAdditionalRunConfigParams
+  & $(Join-Path $PSScriptRoot "run-sdl.ps1") -GuardianCliLocation $guardianCliLocation -WorkingDirectory $workingDirectory -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 -CrScanAdditionalRunConfigParams $CrScanAdditionalRunConfigParams -PoliCheckAdditionalRunConfigParams $PoliCheckAdditionalRunConfigParams
+  & $(Join-Path $PSScriptRoot "run-sdl.ps1") -GuardianCliLocation $guardianCliLocation -WorkingDirectory $workingDirectory -TargetDirectory $SourceDirectory -GdnFolder $gdnFolder -ToolsList $SourceToolsList -AzureDevOpsAccessToken $AzureDevOpsAccessToken -UpdateBaseline $UpdateBaseline -GuardianLoggerLevel $GuardianLoggerLevel -CrScanAdditionalRunConfigParams $CrScanAdditionalRunConfigParams -PoliCheckAdditionalRunConfigParams $PoliCheckAdditionalRunConfigParams
 }
 
 if ($UpdateBaseline) {
@@ -86,8 +87,8 @@ if ($TsaPublish) {
     if (-not $TsaRepositoryName) {
       $TsaRepositoryName = "$($Repository)-$($BranchName)"
     }
-    Write-Host "$guardianCliLocation tsa-publish --all-tools --repository-name `"$TsaRepositoryName`" --branch-name `"$TsaBranchName`" --build-number `"$BuildNumber`" --codebase-name `"$TsaCodebaseName`" --notification-alias `"$TsaNotificationEmail`" --codebase-admin `"$TsaCodebaseAdmin`" --instance-url `"$TsaInstanceUrl`" --project-name `"$TsaProjectName`" --area-path `"$TsaBugAreaPath`" --iteration-path `"$TsaIterationPath`" --working-directory $ArtifactsDirectory --logger-level $GuardianLoggerLevel"
-    & $guardianCliLocation tsa-publish --all-tools --repository-name "$TsaRepositoryName" --branch-name "$TsaBranchName" --build-number "$BuildNumber" --onboard $True --codebase-name "$TsaCodebaseName" --notification-alias "$TsaNotificationEmail" --codebase-admin "$TsaCodebaseAdmin" --instance-url "$TsaInstanceUrl" --project-name "$TsaProjectName" --area-path "$TsaBugAreaPath" --iteration-path "$TsaIterationPath" --working-directory $ArtifactsDirectory  --logger-level $GuardianLoggerLevel
+    Write-Host "$guardianCliLocation tsa-publish --all-tools --repository-name `"$TsaRepositoryName`" --branch-name `"$TsaBranchName`" --build-number `"$BuildNumber`" --codebase-name `"$TsaCodebaseName`" --notification-alias `"$TsaNotificationEmail`" --codebase-admin `"$TsaCodebaseAdmin`" --instance-url `"$TsaInstanceUrl`" --project-name `"$TsaProjectName`" --area-path `"$TsaBugAreaPath`" --iteration-path `"$TsaIterationPath`" --working-directory $workingDirectory --logger-level $GuardianLoggerLevel"
+    & $guardianCliLocation tsa-publish --all-tools --repository-name "$TsaRepositoryName" --branch-name "$TsaBranchName" --build-number "$BuildNumber" --onboard $True --codebase-name "$TsaCodebaseName" --notification-alias "$TsaNotificationEmail" --codebase-admin "$TsaCodebaseAdmin" --instance-url "$TsaInstanceUrl" --project-name "$TsaProjectName" --area-path "$TsaBugAreaPath" --iteration-path "$TsaIterationPath" --working-directory $workingDirectory  --logger-level $GuardianLoggerLevel
     if ($LASTEXITCODE -ne 0) {
       Write-Host "Guardian tsa-publish failed with exit code $LASTEXITCODE."
       exit $LASTEXITCODE

+ 5 - 5
eng/common/sdl/run-sdl.ps1

@@ -32,16 +32,16 @@ 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 `" `" OutputType : pre `" $(If ($CrScanAdditionalRunConfigParams) {$CrScanAdditionalRunConfigParams})"
-    & $GuardianCliLocation configure --working-directory $WorkingDirectory --tool $tool --output-path $gdnConfigFile --logger-level $GuardianLoggerLevel --noninteractive --force --args " TargetDirectory : $TargetDirectory " "OutputType : pre" $(If ($CrScanAdditionalRunConfigParams) {$CrScanAdditionalRunConfigParams})
+    Write-Host "$GuardianCliLocation configure --working-directory $WorkingDirectory --tool $tool --output-path $gdnConfigFile --logger-level $GuardianLoggerLevel --noninteractive --force --args `" TargetDirectory < $TargetDirectory `" `" OutputType < pre `" $(If ($CrScanAdditionalRunConfigParams) {$CrScanAdditionalRunConfigParams})"
+    & $GuardianCliLocation configure --working-directory $WorkingDirectory --tool $tool --output-path $gdnConfigFile --logger-level $GuardianLoggerLevel --noninteractive --force --args " TargetDirectory < $TargetDirectory " "OutputType < pre" $(If ($CrScanAdditionalRunConfigParams) {$CrScanAdditionalRunConfigParams})
     if ($LASTEXITCODE -ne 0) {
       Write-Host "Guardian configure for $tool failed with exit code $LASTEXITCODE."
       exit $LASTEXITCODE
     }
   }
   if ($tool -eq "policheck") {
-    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})
+    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
@@ -56,4 +56,4 @@ Write-Host "$GuardianCliLocation run --working-directory $WorkingDirectory --bas
 if ($LASTEXITCODE -ne 0) {
   Write-Host "Guardian run for $ToolsList using $configParam failed with exit code $LASTEXITCODE."
   exit $LASTEXITCODE
-}
+}

+ 4 - 1
eng/common/templates/job/job.yml

@@ -24,7 +24,7 @@ parameters:
 
   workspace: ''
 
-# Job base template specific parameters
+  # Job base template specific parameters
   # Optional: Enable installing Microbuild plugin
   #           if 'true', these "variables" must be specified in the variables object or as part of the queue matrix
   #             _TeamName - the name of your team
@@ -151,6 +151,9 @@ jobs:
         continueOnError: ${{ parameters.continueOnError }}
         condition: and(succeeded(), in(variables['_SignType'], 'real', 'test'), eq(variables['Agent.Os'], 'Windows_NT'))
 
+  - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}:
+    - task: NuGetAuthenticate@0
+
   - ${{ each step in parameters.steps }}:
     - ${{ step }}
 

+ 5 - 3
eng/common/templates/job/performance.yml

@@ -5,6 +5,7 @@ parameters:
   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
+  osGroup: ''                     # required -- operating system for the job
   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
@@ -19,7 +20,7 @@ jobs:
     enableTelemetry: ${{ parameters.enableTelemetry }}
     enablePublishBuildArtifacts: true
     continueOnError: ${{ parameters.continueOnError }}
-    
+
     jobs:
       - job: '${{ parameters.jobName }}'
 
@@ -44,12 +45,13 @@ jobs:
         - HelixPreCommand: ''
 
         - ${{ if and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}:
-          - ${{ if eq(variables['Agent.Os'], 'Windows_NT') }}:
+          - ${{ if eq( parameters.osGroup, 'Windows_NT') }}:
             - HelixPreCommand: 'set "PERFLAB_UPLOAD_TOKEN=$(PerfCommandUploadToken)"'
             - IsInternal: -Internal
-          - ${{ if ne(variables['Agent.Os'], 'Windows_NT') }}:
+          - ${{ if ne(parameters.osGroup, 'Windows_NT') }}:
             - HelixPreCommand: 'export PERFLAB_UPLOAD_TOKEN="$(PerfCommandUploadTokenLinux)"'
             - IsInternal: --internal
+
           - group: DotNet-HelixApi-Access
           - group: dotnet-benchview
 

+ 7 - 0
eng/common/templates/job/publish-build-assets.yml

@@ -47,6 +47,10 @@ jobs:
         downloadPath: '$(Build.StagingDirectory)/Download'
       condition: ${{ parameters.condition }}
       continueOnError: ${{ parameters.continueOnError }}
+    
+    - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}:
+      - task: NuGetAuthenticate@0
+
     - task: PowerShell@2
       displayName: Publish Build Assets
       inputs:
@@ -59,6 +63,7 @@ jobs:
           /p:Configuration=$(_BuildConfig)
       condition: ${{ parameters.condition }}
       continueOnError: ${{ parameters.continueOnError }}
+    
     - task: powershell@2
       displayName: Create ReleaseConfigs Artifact
       inputs:
@@ -67,12 +72,14 @@ jobs:
           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 $(IsStableBuild)
+    
     - task: PublishBuildArtifacts@1
       displayName: Publish ReleaseConfigs Artifact
       inputs:
         PathtoPublish: '$(Build.StagingDirectory)/ReleaseConfigs.txt'
         PublishLocation: Container
         ArtifactName: ReleaseConfigs
+    
     - ${{ if eq(parameters.enablePublishBuildArtifacts, 'true') }}:
       - task: PublishBuildArtifacts@1
         displayName: Publish Logs to VSTS

+ 26 - 65
eng/common/templates/post-build/channels/public-dev-release.yml → eng/common/templates/post-build/channels/netcore-dev-30.yml

@@ -1,15 +1,14 @@
 parameters:
-  enableSymbolValidation: true
   symbolPublishingAdditionalParameters: ''
   artifactsPublishingAdditionalParameters: ''
   publishInstallersAndChecksums: false
 
 stages:
-- stage: Publish
+- stage: NetCore_Dev30_Publish
   dependsOn: validate
   variables:
     - template: ../common-variables.yml
-  displayName: Developer Channel
+  displayName: .NET Core 3.0 Dev Publishing
   jobs:
   - template: ../setup-maestro-vars.yml
 
@@ -39,15 +38,15 @@ stages:
         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:DotNetSymbolServerTokenMsdl=$(microsoft-symbol-server-pat)
+            /p:DotNetSymbolServerTokenSymWeb=$(symweb-symbol-server-pat)
             /p:PDBArtifactsDirectory='$(Build.ArtifactStagingDirectory)/PDBArtifacts/'
             /p:BlobBasePath='$(Build.ArtifactStagingDirectory)/BlobArtifacts/'
             /p:SymbolPublishingExclusionsFile='$(Build.SourcesDirectory)/eng/SymbolPublishingExclusionsFile.txt'
             /p:Configuration=Release
             ${{ parameters.symbolPublishingAdditionalParameters }}
 
-  - job:
+  - job: publish_assets
     displayName: Publish Assets
     dependsOn: setupMaestroVars
     variables:
@@ -79,22 +78,27 @@ stages:
           buildType: current
           artifactName: AssetManifests
 
+      - task: NuGetToolInstaller@1
+        displayName: 'Install NuGet.exe'
+
+      # This is necessary whenever we want to publish/restore to an AzDO private feed
+      - task: NuGetAuthenticate@0
+        displayName: 'Authenticate to AzDO Feeds'
+
       - task: PowerShell@2
-        displayName: Add Assets Location
+        displayName: Publish Assets
         env:
-          AZURE_DEVOPS_EXT_PAT: $(dn-bot-dnceng-unviersal-packages-rw)
+          AZURE_DEVOPS_EXT_PAT: $(dn-bot-dnceng-universal-packages-rw)
         inputs:
           filePath: eng\common\sdk-task.ps1
           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:NugetPath=$(NuGetExeToolPath)
+            /p:AzdoTargetFeedPAT='$(dn-bot-dnceng-universal-packages-rw)' 
             /p:AzureStorageTargetFeedPAT='$(dotnetfeed-storage-access-key-1)' 
             /p:BARBuildId=$(BARBuildId) 
             /p:MaestroApiEndpoint='$(MaestroApiEndPoint)' 
@@ -108,58 +112,15 @@ stages:
             /p:InstallersAzureAccountKey=$(dotnetcli-storage-key)
             /p:ChecksumsTargetStaticFeed=$(ChecksumsBlobFeedUrl)
             /p:ChecksumsAzureAccountKey=$(dotnetclichecksums-storage-key)
+            /p:PublishToAzureDevOpsNuGetFeeds=true
+            /p:AzureDevOpsStaticShippingFeed='https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet3/nuget/v3/index.json'
+            /p:AzureDevOpsStaticShippingFeedKey='$(dn-bot-dnceng-artifact-feeds-rw)'
+            /p:AzureDevOpsStaticTransportFeed='https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet3-transport/nuget/v3/index.json'
+            /p:AzureDevOpsStaticTransportFeedKey='$(dn-bot-dnceng-artifact-feeds-rw)'
+            /p:AzureDevOpsStaticSymbolsFeed='https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet3-symbols/nuget/v3/index.json'
+            /p:AzureDevOpsStaticSymbolsFeedKey='$(dn-bot-dnceng-artifact-feeds-rw)'
             ${{ parameters.artifactsPublishingAdditionalParameters }}
-        
-      - 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
-  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.PublicDevRelease_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: ../darc-gather-drop.yml
-    parameters:
-      ChannelId: ${{ variables.PublicDevRelease_30_Channel_Id }}
 
-  - template: ../promote-build.yml	
-    parameters:	
-      ChannelId: ${{ variables.PublicDevRelease_30_Channel_Id }}
+      - template: ../../steps/promote-build.yml
+        parameters:
+          ChannelId: ${{ variables.PublicDevRelease_30_Channel_Id }}

+ 126 - 0
eng/common/templates/post-build/channels/netcore-dev-31.yml

@@ -0,0 +1,126 @@
+parameters:
+  symbolPublishingAdditionalParameters: ''
+  artifactsPublishingAdditionalParameters: ''
+  publishInstallersAndChecksums: false
+
+stages:
+- stage: NetCore_Dev31_Publish
+  dependsOn: validate
+  variables:
+    - template: ../common-variables.yml
+  displayName: .NET Core 3.1 Dev Publishing
+  jobs:
+  - template: ../setup-maestro-vars.yml
+
+  - job:
+    displayName: Symbol Publishing
+    dependsOn: setupMaestroVars
+    condition: contains(dependencies.setupMaestroVars.outputs['setReleaseVars.InitialChannels'], format('[{0}]', variables.PublicDevRelease_31_Channel_Id))
+    variables:
+      - group: DotNet-Symbol-Server-Pats
+    pool:
+      vmImage: 'windows-2019'
+    steps:
+      - task: DownloadBuildArtifacts@0
+        displayName: Download Blob Artifacts
+        inputs:
+          artifactName: 'BlobArtifacts'
+        continueOnError: true
+
+      - task: DownloadBuildArtifacts@0
+        displayName: Download PDB Artifacts
+        inputs:
+          artifactName: 'PDBArtifacts'
+        continueOnError: true
+
+      - 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:SymbolPublishingExclusionsFile='$(Build.SourcesDirectory)/eng/SymbolPublishingExclusionsFile.txt'
+            /p:Configuration=Release
+            ${{ parameters.symbolPublishingAdditionalParameters }}
+
+  - 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.PublicDevRelease_31_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: NuGetToolInstaller@1
+        displayName: 'Install NuGet.exe'
+
+      # This is necessary whenever we want to publish/restore to an AzDO private feed
+      - task: NuGetAuthenticate@0
+        displayName: 'Authenticate to AzDO Feeds'
+
+      - task: PowerShell@2
+        displayName: Publish Assets
+        env:
+          AZURE_DEVOPS_EXT_PAT: $(dn-bot-dnceng-universal-packages-rw)
+        inputs:
+          filePath: eng\common\sdk-task.ps1
+          arguments: -task PublishArtifactsInManifest -restore -msbuildEngine dotnet
+            /p:ArtifactsCategory=$(_DotNetArtifactsCategory)
+            /p:IsStableBuild=$(IsStableBuild)
+            /p:IsInternalBuild=$(IsInternalBuild)
+            /p:RepositoryName=$(Build.Repository.Name)
+            /p:CommitSha=$(Build.SourceVersion)
+            /p:NugetPath=$(NuGetExeToolPath)
+            /p:AzdoTargetFeedPAT='$(dn-bot-dnceng-universal-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
+            /p:PublishInstallersAndChecksums=${{ parameters.publishInstallersAndChecksums }}
+            /p:InstallersTargetStaticFeed=$(InstallersBlobFeedUrl)
+            /p:InstallersAzureAccountKey=$(dotnetcli-storage-key)
+            /p:ChecksumsTargetStaticFeed=$(ChecksumsBlobFeedUrl)
+            /p:ChecksumsAzureAccountKey=$(dotnetclichecksums-storage-key)
+            /p:PublishToAzureDevOpsNuGetFeeds=true
+            /p:AzureDevOpsStaticShippingFeed='https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet3.1/nuget/v3/index.json'
+            /p:AzureDevOpsStaticShippingFeedKey='$(dn-bot-dnceng-artifact-feeds-rw)'
+            /p:AzureDevOpsStaticTransportFeed='https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet3.1-transport/nuget/v3/index.json'
+            /p:AzureDevOpsStaticTransportFeedKey='$(dn-bot-dnceng-artifact-feeds-rw)'
+            /p:AzureDevOpsStaticSymbolsFeed='https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet3.1-symbols/nuget/v3/index.json'
+            /p:AzureDevOpsStaticSymbolsFeedKey='$(dn-bot-dnceng-artifact-feeds-rw)'
+            ${{ parameters.artifactsPublishingAdditionalParameters }}
+
+      - template: ../../steps/promote-build.yml
+        parameters:
+          ChannelId: ${{ variables.PublicDevRelease_31_Channel_Id }}

+ 34 - 73
eng/common/templates/post-build/channels/netcore-dev-5.yml

@@ -1,5 +1,4 @@
 parameters:
-  enableSymbolValidation: true
   symbolPublishingAdditionalParameters: ''
   artifactsPublishingAdditionalParameters: ''
   publishInstallersAndChecksums: false
@@ -9,7 +8,7 @@ stages:
   dependsOn: validate
   variables:
     - template: ../common-variables.yml
-  displayName: .NET Core 5 Dev Channel
+  displayName: .NET Core 5 Dev Publishing
   jobs:
   - template: ../setup-maestro-vars.yml
 
@@ -39,15 +38,15 @@ stages:
         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:DotNetSymbolServerTokenMsdl=$(microsoft-symbol-server-pat)
+            /p:DotNetSymbolServerTokenSymWeb=$(symweb-symbol-server-pat)
             /p:PDBArtifactsDirectory='$(Build.ArtifactStagingDirectory)/PDBArtifacts/'
             /p:BlobBasePath='$(Build.ArtifactStagingDirectory)/BlobArtifacts/'
             /p:SymbolPublishingExclusionsFile='$(Build.SourcesDirectory)/eng/SymbolPublishingExclusionsFile.txt'
             /p:Configuration=Release
             ${{ parameters.symbolPublishingAdditionalParameters }}
 
-  - job:
+  - job: publish_assets
     displayName: Publish Assets
     dependsOn: setupMaestroVars
     variables:
@@ -79,87 +78,49 @@ stages:
           buildType: current
           artifactName: AssetManifests
 
+      - task: NuGetToolInstaller@1
+        displayName: 'Install NuGet.exe'
+
+      # This is necessary whenever we want to publish/restore to an AzDO private feed
+      - task: NuGetAuthenticate@0
+        displayName: 'Authenticate to AzDO Feeds'
+
       - task: PowerShell@2
-        displayName: Add Assets Location
+        displayName: Publish Assets
         env:
-          AZURE_DEVOPS_EXT_PAT: $(dn-bot-dnceng-unviersal-packages-rw)
+          AZURE_DEVOPS_EXT_PAT: $(dn-bot-dnceng-universal-packages-rw)
         inputs:
           filePath: eng\common\sdk-task.ps1
-          arguments: -task PublishArtifactsInManifest -restore -msbuildEngine dotnet 
-            /p:ChannelId=$(NetCore_5_Dev_Channel_Id)
+          arguments: -task PublishArtifactsInManifest -restore -msbuildEngine dotnet
             /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:NugetPath=$(NuGetExeToolPath)
+            /p:AzdoTargetFeedPAT='$(dn-bot-dnceng-universal-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
+            /p:PublishInstallersAndChecksums=${{ parameters.publishInstallersAndChecksums }}
             /p:InstallersTargetStaticFeed=$(InstallersBlobFeedUrl)
             /p:InstallersAzureAccountKey=$(dotnetcli-storage-key)
-            /p:PublishInstallersAndChecksums=${{ parameters.publishInstallersAndChecksums }}
             /p:ChecksumsTargetStaticFeed=$(ChecksumsBlobFeedUrl)
             /p:ChecksumsAzureAccountKey=$(dotnetclichecksums-storage-key)
+            /p:PublishToAzureDevOpsNuGetFeeds=true
+            /p:AzureDevOpsStaticShippingFeed='https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet5/nuget/v3/index.json'
+            /p:AzureDevOpsStaticShippingFeedKey='$(dn-bot-dnceng-artifact-feeds-rw)'
+            /p:AzureDevOpsStaticTransportFeed='https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet5-transport/nuget/v3/index.json'
+            /p:AzureDevOpsStaticTransportFeedKey='$(dn-bot-dnceng-artifact-feeds-rw)'
+            /p:AzureDevOpsStaticSymbolsFeed='https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet5-symbols/nuget/v3/index.json'
+            /p:AzureDevOpsStaticSymbolsFeedKey='$(dn-bot-dnceng-artifact-feeds-rw)'
             ${{ parameters.artifactsPublishingAdditionalParameters }}
-        
-      - 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 }}
+      - template: ../../steps/promote-build.yml
+        parameters:
+          ChannelId: ${{ variables.NetCore_5_Dev_Channel_Id }}

+ 37 - 71
eng/common/templates/post-build/channels/internal-servicing.yml → eng/common/templates/post-build/channels/netcore-internal-30.yml

@@ -1,14 +1,13 @@
 parameters:
-  enableSymbolValidation: true
   symbolPublishingAdditionalParameters: ''
   artifactsPublishingAdditionalParameters: ''
 
 stages:
-- stage: IS_Publish
+- stage: NetCore_30_Internal_Servicing_Publishing
   dependsOn: validate
   variables:
     - template: ../common-variables.yml
-  displayName: Internal Servicing
+  displayName: .NET Core 3.0 Internal Servicing Publishing
   jobs:
   - template: ../setup-maestro-vars.yml
 
@@ -38,8 +37,8 @@ stages:
         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:DotNetSymbolServerTokenMsdl=$(microsoft-symbol-server-pat)
+            /p:DotNetSymbolServerTokenSymWeb=$(symweb-symbol-server-pat)
             /p:PDBArtifactsDirectory='$(Build.ArtifactStagingDirectory)/PDBArtifacts/'
             /p:BlobBasePath='$(Build.ArtifactStagingDirectory)/BlobArtifacts/'
             /p:SymbolPublishingExclusionsFile='$(Build.SourcesDirectory)/eng/SymbolPublishingExclusionsFile.txt'
@@ -78,81 +77,48 @@ stages:
           buildType: current
           artifactName: AssetManifests
 
+      - task: NuGetToolInstaller@1
+        displayName: 'Install NuGet.exe'
+
+      # This is necessary whenever we want to publish/restore to an AzDO private feed
+      - task: NuGetAuthenticate@0
+        displayName: 'Authenticate to AzDO Feeds'
+
       - task: PowerShell@2
-        displayName: Add Assets Location
+        displayName: Publish Assets
         env:
-          AZURE_DEVOPS_EXT_PAT: $(dn-bot-dnceng-unviersal-packages-rw)
+          AZURE_DEVOPS_EXT_PAT: $(dn-bot-dnceng-universal-packages-rw)
         inputs:
           filePath: eng\common\sdk-task.ps1
-          arguments: -task PublishArtifactsInManifest -restore -msbuildEngine dotnet 
-            /p:ChannelId=$(InternalServicing_30_Channel_Id)
+          arguments: -task PublishArtifactsInManifest -restore -msbuildEngine dotnet
             /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 
+            /p:NugetPath=$(NuGetExeToolPath)
+            /p:AzdoTargetFeedPAT='$(dn-bot-dnceng-universal-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
+            /p:PublishInstallersAndChecksums=true
+            /p:ChecksumsTargetStaticFeed=$(InternalChecksumsBlobFeedUrl)
+            /p:ChecksumsAzureAccountKey=$(InternalChecksumsBlobFeedKey)
+            /p:InstallersTargetStaticFeed=$(InternalInstallersBlobFeedUrl)
+            /p:InstallersAzureAccountKey=$(InternalInstallersBlobFeedKey)
+            /p:PublishToAzureDevOpsNuGetFeeds=true
+            /p:AzureDevOpsStaticShippingFeed='https://pkgs.dev.azure.com/dnceng/_packaging/dotnet3-internal/nuget/v3/index.json'
+            /p:AzureDevOpsStaticShippingFeedKey='$(dn-bot-dnceng-artifact-feeds-rw)'
+            /p:AzureDevOpsStaticTransportFeed='https://pkgs.dev.azure.com/dnceng/_packaging/dotnet3-internal-transport/nuget/v3/index.json'
+            /p:AzureDevOpsStaticTransportFeedKey='$(dn-bot-dnceng-artifact-feeds-rw)'
+            /p:AzureDevOpsStaticSymbolsFeed='https://pkgs.dev.azure.com/dnceng/_packaging/dotnet3-internal-symbols/nuget/v3/index.json'
+            /p:AzureDevOpsStaticSymbolsFeedKey='$(dn-bot-dnceng-artifact-feeds-rw)'
             ${{ parameters.artifactsPublishingAdditionalParameters }}
-        
-      - 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
+      - template: ../../steps/promote-build.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 }}

+ 39 - 72
eng/common/templates/post-build/channels/public-release.yml → eng/common/templates/post-build/channels/netcore-release-30.yml

@@ -1,14 +1,14 @@
 parameters:
-  enableSymbolValidation: true
   symbolPublishingAdditionalParameters: ''
   artifactsPublishingAdditionalParameters: ''
+  publishInstallersAndChecksums: false
 
 stages:
-- stage: PubRel_Publish
+- stage: NetCore_Release30_Publish
   dependsOn: validate
   variables:
     - template: ../common-variables.yml
-  displayName: Public Release
+  displayName: .NET Core 3.0 Release Publishing
   jobs:
   - template: ../setup-maestro-vars.yml
 
@@ -38,8 +38,8 @@ stages:
         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:DotNetSymbolServerTokenMsdl=$(microsoft-symbol-server-pat)
+            /p:DotNetSymbolServerTokenSymWeb=$(symweb-symbol-server-pat)
             /p:PDBArtifactsDirectory='$(Build.ArtifactStagingDirectory)/PDBArtifacts/'
             /p:BlobBasePath='$(Build.ArtifactStagingDirectory)/BlobArtifacts/'
             /p:SymbolPublishingExclusionsFile='$(Build.SourcesDirectory)/eng/SymbolPublishingExclusionsFile.txt'
@@ -78,82 +78,49 @@ stages:
           buildType: current
           artifactName: AssetManifests
 
+      - task: NuGetToolInstaller@1
+        displayName: 'Install NuGet.exe'
+
+      # This is necessary whenever we want to publish/restore to an AzDO private feed
+      - task: NuGetAuthenticate@0
+        displayName: 'Authenticate to AzDO Feeds'
+
       - task: PowerShell@2
-        displayName: Publish
+        displayName: Publish Assets
         env:
-          AZURE_DEVOPS_EXT_PAT: $(dn-bot-dnceng-unviersal-packages-rw)
+          AZURE_DEVOPS_EXT_PAT: $(dn-bot-dnceng-universal-packages-rw)
         inputs:
           filePath: eng\common\sdk-task.ps1
-          arguments: -task PublishArtifactsInManifest -restore -msbuildEngine dotnet 
-            /p:ChannelId=$(PublicRelease_30_Channel_Id)
+          arguments: -task PublishArtifactsInManifest -restore -msbuildEngine dotnet
+            /p:ArtifactsCategory=$(_DotNetArtifactsCategory)
             /p:IsStableBuild=$(IsStableBuild)
             /p:IsInternalBuild=$(IsInternalBuild)
             /p:RepositoryName=$(Build.Repository.Name)
             /p:CommitSha=$(Build.SourceVersion)
-            /p:AzureStorageTargetFeedPAT='$(dotnetfeed-storage-access-key-1)' 
-            /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 
+            /p:NugetPath=$(NuGetExeToolPath)
+            /p:AzdoTargetFeedPAT='$(dn-bot-dnceng-universal-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
+            /p:PublishInstallersAndChecksums=${{ parameters.publishInstallersAndChecksums }}
+            /p:InstallersTargetStaticFeed=$(InstallersBlobFeedUrl)
+            /p:InstallersAzureAccountKey=$(dotnetcli-storage-key)
+            /p:ChecksumsTargetStaticFeed=$(ChecksumsBlobFeedUrl)
+            /p:ChecksumsAzureAccountKey=$(dotnetclichecksums-storage-key)
+            /p:PublishToAzureDevOpsNuGetFeeds=true
+            /p:AzureDevOpsStaticShippingFeed='https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet3/nuget/v3/index.json'
+            /p:AzureDevOpsStaticShippingFeedKey='$(dn-bot-dnceng-artifact-feeds-rw)'
+            /p:AzureDevOpsStaticTransportFeed='https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet3-transport/nuget/v3/index.json'
+            /p:AzureDevOpsStaticTransportFeedKey='$(dn-bot-dnceng-artifact-feeds-rw)'
+            /p:AzureDevOpsStaticSymbolsFeed='https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet3-symbols/nuget/v3/index.json'
+            /p:AzureDevOpsStaticSymbolsFeedKey='$(dn-bot-dnceng-artifact-feeds-rw)'
             ${{ parameters.artifactsPublishingAdditionalParameters }}
-        
-      - 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
+      - template: ../../steps/promote-build.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 }}

+ 126 - 0
eng/common/templates/post-build/channels/netcore-release-31.yml

@@ -0,0 +1,126 @@
+parameters:
+  symbolPublishingAdditionalParameters: ''
+  artifactsPublishingAdditionalParameters: ''
+  publishInstallersAndChecksums: false
+
+stages:
+- stage: NetCore_Release31_Publish
+  dependsOn: validate
+  variables:
+    - template: ../common-variables.yml
+  displayName: .NET Core 3.1 Release Publishing
+  jobs:
+  - template: ../setup-maestro-vars.yml
+
+  - job:
+    displayName: Symbol Publishing
+    dependsOn: setupMaestroVars
+    condition: contains(dependencies.setupMaestroVars.outputs['setReleaseVars.InitialChannels'], format('[{0}]', variables.PublicRelease_31_Channel_Id))
+    variables:
+      - group: DotNet-Symbol-Server-Pats
+    pool:
+      vmImage: 'windows-2019'
+    steps:
+      - task: DownloadBuildArtifacts@0
+        displayName: Download Blob Artifacts
+        inputs:
+          artifactName: 'BlobArtifacts'
+        continueOnError: true
+
+      - task: DownloadBuildArtifacts@0
+        displayName: Download PDB Artifacts
+        inputs:
+          artifactName: 'PDBArtifacts'
+        continueOnError: true
+
+      - 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:SymbolPublishingExclusionsFile='$(Build.SourcesDirectory)/eng/SymbolPublishingExclusionsFile.txt'
+            /p:Configuration=Release
+            ${{ parameters.symbolPublishingAdditionalParameters }}
+
+  - 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_31_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: NuGetToolInstaller@1
+        displayName: 'Install NuGet.exe'
+
+      # This is necessary whenever we want to publish/restore to an AzDO private feed
+      - task: NuGetAuthenticate@0
+        displayName: 'Authenticate to AzDO Feeds'
+
+      - task: PowerShell@2
+        displayName: Publish Assets
+        env:
+          AZURE_DEVOPS_EXT_PAT: $(dn-bot-dnceng-universal-packages-rw)
+        inputs:
+          filePath: eng\common\sdk-task.ps1
+          arguments: -task PublishArtifactsInManifest -restore -msbuildEngine dotnet
+            /p:ArtifactsCategory=$(_DotNetArtifactsCategory)
+            /p:IsStableBuild=$(IsStableBuild)
+            /p:IsInternalBuild=$(IsInternalBuild)
+            /p:RepositoryName=$(Build.Repository.Name)
+            /p:CommitSha=$(Build.SourceVersion)
+            /p:NugetPath=$(NuGetExeToolPath)
+            /p:AzdoTargetFeedPAT='$(dn-bot-dnceng-universal-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
+            /p:PublishInstallersAndChecksums=${{ parameters.publishInstallersAndChecksums }}
+            /p:InstallersTargetStaticFeed=$(InstallersBlobFeedUrl)
+            /p:InstallersAzureAccountKey=$(dotnetcli-storage-key)
+            /p:ChecksumsTargetStaticFeed=$(ChecksumsBlobFeedUrl)
+            /p:ChecksumsAzureAccountKey=$(dotnetclichecksums-storage-key)
+            /p:PublishToAzureDevOpsNuGetFeeds=true
+            /p:AzureDevOpsStaticShippingFeed='https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet3.1/nuget/v3/index.json'
+            /p:AzureDevOpsStaticShippingFeedKey='$(dn-bot-dnceng-artifact-feeds-rw)'
+            /p:AzureDevOpsStaticTransportFeed='https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet3.1-transport/nuget/v3/index.json'
+            /p:AzureDevOpsStaticTransportFeedKey='$(dn-bot-dnceng-artifact-feeds-rw)'
+            /p:AzureDevOpsStaticSymbolsFeed='https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet3.1-symbols/nuget/v3/index.json'
+            /p:AzureDevOpsStaticSymbolsFeedKey='$(dn-bot-dnceng-artifact-feeds-rw)'
+            ${{ parameters.artifactsPublishingAdditionalParameters }}
+
+      - template: ../../steps/promote-build.yml
+        parameters:
+          ChannelId: ${{ variables.PublicRelease_31_Channel_Id }}

+ 34 - 73
eng/common/templates/post-build/channels/netcore-tools-latest.yml

@@ -1,5 +1,4 @@
 parameters:
-  enableSymbolValidation: true
   symbolPublishingAdditionalParameters: ''
   artifactsPublishingAdditionalParameters: ''
   publishInstallersAndChecksums: false
@@ -9,7 +8,7 @@ stages:
   dependsOn: validate
   variables:
     - template: ../common-variables.yml
-  displayName: .NET Tools - Latest
+  displayName: .NET Tools - Latest Publishing
   jobs:
   - template: ../setup-maestro-vars.yml
 
@@ -39,15 +38,15 @@ stages:
         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:DotNetSymbolServerTokenMsdl=$(microsoft-symbol-server-pat)
+            /p:DotNetSymbolServerTokenSymWeb=$(symweb-symbol-server-pat)
             /p:PDBArtifactsDirectory='$(Build.ArtifactStagingDirectory)/PDBArtifacts/'
             /p:BlobBasePath='$(Build.ArtifactStagingDirectory)/BlobArtifacts/'
             /p:SymbolPublishingExclusionsFile='$(Build.SourcesDirectory)/eng/SymbolPublishingExclusionsFile.txt'
             /p:Configuration=Release
             ${{ parameters.symbolPublishingAdditionalParameters }}
 
-  - job:
+  - job: publish_assets
     displayName: Publish Assets
     dependsOn: setupMaestroVars
     variables:
@@ -79,87 +78,49 @@ stages:
           buildType: current
           artifactName: AssetManifests
 
+      - task: NuGetToolInstaller@1
+        displayName: 'Install NuGet.exe'
+
+      # This is necessary whenever we want to publish/restore to an AzDO private feed
+      - task: NuGetAuthenticate@0
+        displayName: 'Authenticate to AzDO Feeds'
+
       - task: PowerShell@2
-        displayName: Add Assets Location
+        displayName: Publish Assets
         env:
-          AZURE_DEVOPS_EXT_PAT: $(dn-bot-dnceng-unviersal-packages-rw)
+          AZURE_DEVOPS_EXT_PAT: $(dn-bot-dnceng-universal-packages-rw)
         inputs:
           filePath: eng\common\sdk-task.ps1
-          arguments: -task PublishArtifactsInManifest -restore -msbuildEngine dotnet 
-            /p:ChannelId=$(NetCore_Tools_Latest_Channel_Id)
+          arguments: -task PublishArtifactsInManifest -restore -msbuildEngine dotnet
             /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:NugetPath=$(NuGetExeToolPath)
+            /p:AzdoTargetFeedPAT='$(dn-bot-dnceng-universal-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
-            /p:InstallersTargetStaticFeed=$(InstallersBlobFeedUrl)
             /p:PublishInstallersAndChecksums=${{ parameters.publishInstallersAndChecksums }}
+            /p:InstallersTargetStaticFeed=$(InstallersBlobFeedUrl)
             /p:InstallersAzureAccountKey=$(dotnetcli-storage-key)
             /p:ChecksumsTargetStaticFeed=$(ChecksumsBlobFeedUrl)
             /p:ChecksumsAzureAccountKey=$(dotnetclichecksums-storage-key)
+            /p:PublishToAzureDevOpsNuGetFeeds=true
+            /p:AzureDevOpsStaticShippingFeed='https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json'
+            /p:AzureDevOpsStaticShippingFeedKey='$(dn-bot-dnceng-artifact-feeds-rw)'
+            /p:AzureDevOpsStaticTransportFeed='https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json'
+            /p:AzureDevOpsStaticTransportFeedKey='$(dn-bot-dnceng-artifact-feeds-rw)'
+            /p:AzureDevOpsStaticSymbolsFeed='https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools-symbols/nuget/v3/index.json'
+            /p:AzureDevOpsStaticSymbolsFeedKey='$(dn-bot-dnceng-artifact-feeds-rw)'
             ${{ parameters.artifactsPublishingAdditionalParameters }}
-        
-      - 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 }}
+      - template: ../../steps/promote-build.yml
+        parameters:
+          ChannelId: ${{ variables.NetCore_Tools_Latest_Channel_Id }}

+ 32 - 50
eng/common/templates/post-build/channels/public-validation-release.yml

@@ -7,11 +7,11 @@ stages:
   dependsOn: validate
   variables:
     - template: ../common-variables.yml
-  displayName: Validation Channel
+  displayName: .NET Tools - Validation Publishing
   jobs:
   - template: ../setup-maestro-vars.yml
 
-  - job:
+  - job: publish_assets
     displayName: Publish Assets
     dependsOn: setupMaestroVars
     variables:
@@ -43,67 +43,49 @@ stages:
           buildType: current
           artifactName: AssetManifests
 
+      - task: NuGetToolInstaller@1
+        displayName: 'Install NuGet.exe'
+
+      # This is necessary whenever we want to publish/restore to an AzDO private feed
+      - task: NuGetAuthenticate@0
+        displayName: 'Authenticate to AzDO Feeds'
+
       - task: PowerShell@2
-        displayName: Add Assets Location
+        displayName: Publish Assets
         env:
-          AZURE_DEVOPS_EXT_PAT: $(dn-bot-dnceng-unviersal-packages-rw)
+          AZURE_DEVOPS_EXT_PAT: $(dn-bot-dnceng-universal-packages-rw)
         inputs:
           filePath: eng\common\sdk-task.ps1
-          arguments: -task PublishArtifactsInManifest -restore -msbuildEngine dotnet 
-            /p:ChannelId=$(PublicValidationRelease_30_Channel_Id)
+          arguments: -task PublishArtifactsInManifest -restore -msbuildEngine dotnet
             /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='$(MaestroApiEndPoint)' 
-            /p:BuildAssetRegistryToken='$(MaestroApiAccessToken)' 
-            /p:ManifestsBasePath='$(Build.ArtifactStagingDirectory)/AssetManifests/' 
-            /p:BlobBasePath='$(Build.ArtifactStagingDirectory)\BlobArtifacts' 
-            /p:PackageBasePath='$(Build.ArtifactStagingDirectory)\PackageArtifacts' 
+            /p:NugetPath=$(NuGetExeToolPath)
+            /p:AzdoTargetFeedPAT='$(dn-bot-dnceng-universal-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
+            /p:PublishInstallersAndChecksums=${{ parameters.publishInstallersAndChecksums }}
             /p:InstallersTargetStaticFeed=$(InstallersBlobFeedUrl)
             /p:InstallersAzureAccountKey=$(dotnetcli-storage-key)
-            /p:PublishInstallersAndChecksums=${{ parameters.publishInstallersAndChecksums }}
             /p:ChecksumsTargetStaticFeed=$(ChecksumsBlobFeedUrl)
             /p:ChecksumsAzureAccountKey=$(dotnetclichecksums-storage-key)
+            /p:PublishToAzureDevOpsNuGetFeeds=true
+            /p:AzureDevOpsStaticShippingFeed='https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json'
+            /p:AzureDevOpsStaticShippingFeedKey='$(dn-bot-dnceng-artifact-feeds-rw)'
+            /p:AzureDevOpsStaticTransportFeed='https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json'
+            /p:AzureDevOpsStaticTransportFeedKey='$(dn-bot-dnceng-artifact-feeds-rw)'
+            /p:AzureDevOpsStaticSymbolsFeed='https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools-symbols/nuget/v3/index.json'
+            /p:AzureDevOpsStaticSymbolsFeedKey='$(dn-bot-dnceng-artifact-feeds-rw)'
             ${{ parameters.artifactsPublishingAdditionalParameters }}
 
-      - 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
-  variables:
-    - template: ../common-variables.yml
-  jobs:
-  - template: ../setup-maestro-vars.yml
-
-  - template: ../darc-gather-drop.yml
-    parameters:
-      ChannelId: ${{ variables.PublicValidationRelease_30_Channel_Id }}
-
-  - template: ../promote-build.yml	
-    parameters:	
-      ChannelId: ${{ variables.PublicValidationRelease_30_Channel_Id }}
+      - template: ../../steps/promote-build.yml
+        parameters:
+          ChannelId: ${{ variables.PublicValidationRelease_30_Channel_Id }}

+ 26 - 6
eng/common/templates/post-build/common-variables.yml

@@ -1,11 +1,16 @@
 variables:
   - group: Publish-Build-Assets
   - group: DotNet-DotNetCli-Storage
+  - group: DotNet-MSRC-Storage
 
   # .NET Core 3 Dev
   - name: PublicDevRelease_30_Channel_Id
     value: 3
 
+  # .NET Core 3.1 Dev
+  - name: PublicDevRelease_31_Channel_Id
+    value: 128
+
   # .NET Core 5 Dev
   - name: NetCore_5_Dev_Channel_Id
     value: 131
@@ -26,14 +31,14 @@ variables:
   - name: PublicRelease_30_Channel_Id
     value: 19
 
+  # .NET Core 3.1 Release
+  - name: PublicRelease_31_Channel_Id
+    value: 129
+
   # 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"
@@ -47,8 +52,23 @@ variables:
   - name: SymbolToolVersion
     value: 1.0.1
 
+  # Feed Configurations
+  # These should include the suffix "/index.json"
+
   # Default locations for Installers and checksums
+  # Public Locations
   - name: ChecksumsBlobFeedUrl
-    value: https://dotnetcli.blob.core.windows.net/dotnet/index.json
-  - name: InstallersBlobFeedUrl
     value: https://dotnetclichecksums.blob.core.windows.net/dotnet/index.json
+  - name: InstallersBlobFeedUrl
+    value: https://dotnetcli.blob.core.windows.net/dotnet/index.json
+
+  # Private Locations
+  - name: InternalChecksumsBlobFeedUrl
+    value: https://dotnetclichecksumsmsrc.blob.core.windows.net/dotnet/index.json
+  - name: InternalChecksumsBlobFeedKey
+    value: $(dotnetclichecksumsmsrc-storage-key)
+
+  - name: InternalInstallersBlobFeedUrl
+    value: https://dotnetclimsrc.blob.core.windows.net/dotnet/index.json
+  - name: InternalInstallersBlobFeedKey
+    value: $(dotnetclimsrc-access-key)

+ 16 - 6
eng/common/templates/post-build/post-build.yml

@@ -97,21 +97,24 @@ stages:
 
 - template: \eng\common\templates\post-build\channels\netcore-dev-5.yml
   parameters:
-    enableSymbolValidation: ${{ parameters.enableSymbolValidation }}
     symbolPublishingAdditionalParameters: ${{ parameters.symbolPublishingAdditionalParameters }}
     artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }}
     publishInstallersAndChecksums: ${{ parameters.publishInstallersAndChecksums }}
 
-- template: \eng\common\templates\post-build\channels\public-dev-release.yml
+- template: \eng\common\templates\post-build\channels\netcore-dev-30.yml
+  parameters:
+    symbolPublishingAdditionalParameters: ${{ parameters.symbolPublishingAdditionalParameters }}
+    artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }}
+    publishInstallersAndChecksums: ${{ parameters.publishInstallersAndChecksums }}
+
+- template: \eng\common\templates\post-build\channels\netcore-dev-31.yml
   parameters:
-    enableSymbolValidation: ${{ parameters.enableSymbolValidation }}
     symbolPublishingAdditionalParameters: ${{ parameters.symbolPublishingAdditionalParameters }}
     artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }}
     publishInstallersAndChecksums: ${{ parameters.publishInstallersAndChecksums }}
 
 - template: \eng\common\templates\post-build\channels\netcore-tools-latest.yml
   parameters:
-    enableSymbolValidation: ${{ parameters.enableSymbolValidation }}
     symbolPublishingAdditionalParameters: ${{ parameters.symbolPublishingAdditionalParameters }}
     artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }}
     publishInstallersAndChecksums: ${{ parameters.publishInstallersAndChecksums }}
@@ -121,12 +124,19 @@ stages:
     artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }}
     publishInstallersAndChecksums: ${{ parameters.publishInstallersAndChecksums }}
 
-- template: \eng\common\templates\post-build\channels\public-release.yml
+- template: \eng\common\templates\post-build\channels\netcore-release-30.yml
   parameters:
     symbolPublishingAdditionalParameters: ${{ parameters.symbolPublishingAdditionalParameters }}
     artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }}
+    publishInstallersAndChecksums: ${{ parameters.publishInstallersAndChecksums }}
+
+- template: \eng\common\templates\post-build\channels\netcore-release-31.yml
+  parameters:
+    symbolPublishingAdditionalParameters: ${{ parameters.symbolPublishingAdditionalParameters }}
+    artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }}
+    publishInstallersAndChecksums: ${{ parameters.publishInstallersAndChecksums }}
 
-- template: \eng\common\templates\post-build\channels\internal-servicing.yml
+- template: \eng\common\templates\post-build\channels\netcore-internal-30.yml
   parameters:
     symbolPublishingAdditionalParameters: ${{ parameters.symbolPublishingAdditionalParameters }}
     artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }}

+ 13 - 0
eng/common/templates/steps/promote-build.yml

@@ -0,0 +1,13 @@
+parameters:
+  ChannelId: 0
+
+steps:
+- task: PowerShell@2
+  displayName: Add Build to Channel
+  inputs:
+    filePath: $(Build.SourcesDirectory)/eng/common/post-build/promote-build.ps1
+    arguments: -BuildId $(BARBuildId) 
+      -ChannelId ${{ parameters.ChannelId }}
+      -MaestroApiAccessToken $(MaestroApiAccessToken)
+      -MaestroApiEndPoint $(MaestroApiEndPoint)
+      -MaestroApiVersion $(MaestroApiVersion)

+ 17 - 1
eng/common/tools.ps1

@@ -153,6 +153,16 @@ function InitializeDotNetCli([bool]$install) {
 
   # Make Sure that our bootstrapped dotnet cli is available in future steps of the Azure Pipelines build
   Write-PipelinePrependPath -Path $dotnetRoot
+
+  # Work around issues with Azure Artifacts credential provider
+  # https://github.com/dotnet/arcade/issues/3932
+  if ($ci) {
+    $env:NUGET_PLUGIN_HANDSHAKE_TIMEOUT_IN_SECONDS = 20
+    $env:NUGET_PLUGIN_REQUEST_TIMEOUT_IN_SECONDS = 20
+    Write-PipelineSetVariable -Name 'NUGET_PLUGIN_HANDSHAKE_TIMEOUT_IN_SECONDS' -Value '20'
+    Write-PipelineSetVariable -Name 'NUGET_PLUGIN_REQUEST_TIMEOUT_IN_SECONDS' -Value '20'
+  }
+
   Write-PipelineSetVariable -Name 'DOTNET_MULTILEVEL_LOOKUP' -Value '0'
   Write-PipelineSetVariable -Name 'DOTNET_SKIP_FIRST_TIME_EXPERIENCE' -Value '1'
 
@@ -365,7 +375,6 @@ function InitializeBuildTool() {
       Write-PipelineTelemetryError -Category "InitializeToolset" -Message "/global.json must specify 'tools.dotnet'."
       ExitWithExitCode 1
     }
-
     $buildTool = @{ Path = Join-Path $dotnetRoot "dotnet.exe"; Command = "msbuild"; Tool = "dotnet"; Framework = "netcoreapp2.1" }
   } elseif ($msbuildEngine -eq "vs") {
     try {
@@ -490,6 +499,13 @@ function Stop-Processes() {
 function MSBuild() {
   if ($pipelinesLog) {
     $buildTool = InitializeBuildTool
+
+    # Work around issues with Azure Artifacts credential provider
+    # https://github.com/dotnet/arcade/issues/3932
+    if ($ci -and $buildTool.Tool -eq "dotnet") {
+      dotnet nuget locals http-cache -c
+    }
+
     $toolsetBuildProject = InitializeToolset
     $path = Split-Path -parent $toolsetBuildProject
     $path = Join-Path $path (Join-Path $buildTool.Framework "Microsoft.DotNet.Arcade.Sdk.dll")

+ 16 - 0
eng/common/tools.sh

@@ -152,6 +152,15 @@ function InitializeDotNetCli {
   # build steps from using anything other than what we've downloaded.
   Write-PipelinePrependPath -path "$dotnet_root"
 
+  # Work around issues with Azure Artifacts credential provider
+  # https://github.com/dotnet/arcade/issues/3932
+  if [[ "$ci" == true ]]; then
+    export NUGET_PLUGIN_HANDSHAKE_TIMEOUT_IN_SECONDS=20
+    export NUGET_PLUGIN_REQUEST_TIMEOUT_IN_SECONDS=20
+    Write-PipelineSetVariable -name "NUGET_PLUGIN_HANDSHAKE_TIMEOUT_IN_SECONDS" -value "20"
+    Write-PipelineSetVariable -name "NUGET_PLUGIN_REQUEST_TIMEOUT_IN_SECONDS" -value "20"
+  fi
+
   Write-PipelineSetVariable -name "DOTNET_MULTILEVEL_LOOKUP" -value "0"
   Write-PipelineSetVariable -name "DOTNET_SKIP_FIRST_TIME_EXPERIENCE" -value "1"
 
@@ -328,6 +337,13 @@ function MSBuild {
   if [[ "$pipelines_log" == true ]]; then
     InitializeBuildTool
     InitializeToolset
+
+    # Work around issues with Azure Artifacts credential provider
+    # https://github.com/dotnet/arcade/issues/3932
+    if [[ "$ci" == true ]]; then
+      dotnet nuget locals http-cache -c
+    fi
+
     local toolset_dir="${_InitializeToolset%/*}"
     local logger_path="$toolset_dir/$_InitializeBuildToolFramework/Microsoft.DotNet.Arcade.Sdk.dll"
     args=( "${args[@]}" "-logger:$logger_path" )

+ 2 - 1
eng/docker/alpine.Dockerfile

@@ -2,8 +2,9 @@ FROM microsoft/dotnet:2.1.0-preview1-runtime-deps-alpine
 ARG USER
 ARG USER_ID
 ARG GROUP_ID
+ARG WORKDIR
 
-WORKDIR /code/build
+WORKDIR ${WORKDIR}
 RUN mkdir -p "/home/$USER" && chown "${USER_ID}:${GROUP_ID}" "/home/$USER"
 ENV HOME "/home/$USER"
 

+ 2 - 1
eng/docker/bionic.Dockerfile

@@ -3,8 +3,9 @@ FROM microsoft/dotnet:2.1-runtime-deps-bionic
 ARG USER
 ARG USER_ID
 ARG GROUP_ID
+ARG WORKDIR
 
-WORKDIR /code/build
+WORKDIR ${WORKDIR}
 RUN mkdir -p "/home/$USER" && chown "${USER_ID}:${GROUP_ID}" "/home/$USER"
 ENV HOME "/home/$USER"
 

+ 2 - 1
eng/docker/rhel.Dockerfile

@@ -5,8 +5,9 @@ FROM mcr.microsoft.com/dotnet-buildtools/prereqs:rhel-7-rpmpkg-e1b4a89-201753110
 ARG USER
 ARG USER_ID
 ARG GROUP_ID
+ARG WORKDIR
 
-WORKDIR /code/build
+WORKDIR ${WORKDIR}
 
 RUN useradd -m ${USER} --uid ${USER_ID} -g root
 RUN echo '${USER} ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers

+ 2 - 1
eng/docker/ubuntu-alpine37.Dockerfile

@@ -2,8 +2,9 @@ FROM mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-16.04-cross-arm64-alpine
 ARG USER
 ARG USER_ID
 ARG GROUP_ID
+ARG WORKDIR
 
-WORKDIR /code/build
+WORKDIR ${WORKDIR}
 RUN mkdir -p "/home/$USER" && chown "${USER_ID}:${GROUP_ID}" "/home/$USER"
 ENV HOME "/home/$USER"
 

+ 5 - 0
eng/empty.proj

@@ -0,0 +1,5 @@
+<!-- eng\common\build.ps1 fails without a project to build, so we give it this empty project to satisfy its desires -->
+<Project>
+  <Import Project="Sdk.props" Sdk="Microsoft.DotNet.Arcade.Sdk" />
+  <Import Project="Sdk.targets" Sdk="Microsoft.DotNet.Arcade.Sdk" />
+</Project>

+ 76 - 0
eng/scripts/FinishDumpCollectionForHangingBuilds.ps1

@@ -0,0 +1,76 @@
+param(
+  [Parameter(Mandatory = $true)]
+  [ValidateNotNullOrEmpty()]
+  [string]
+  $ProcDumpOutputPath
+)
+
+Write-Output "Finishing dump collection for hanging builds.";
+
+$repoRoot = Resolve-Path "$PSScriptRoot\..\..";
+$ProcDumpOutputPath = Join-Path $repoRoot $ProcDumpOutputPath;
+
+$sentinelFile = Join-Path $ProcDumpOutputPath "dump-sentinel.txt";
+if ((-not (Test-Path $sentinelFile))) {
+  Write-Output "No sentinel file available in '$sentinelFile'. " +
+    "StartDumpCollectionForHangingBuilds.ps1 has not been executed, is not correctly configured or failed before creating the sentinel file.";
+  return;
+}
+
+Get-Process "procdump" -ErrorAction SilentlyContinue | ForEach-Object { Write-Output "ProcDump with PID $($_.Id) is still running."; };
+
+$capturedDumps = Get-ChildItem $ProcDumpOutputPath -Filter *.dmp;
+$capturedDumps | ForEach-Object { Write-Output "Found captured dump $_"; };
+
+$JobName = (Get-Content $sentinelFile);
+
+if ($JobName.Count -ne 1) {
+  if ($JobName.Count -eq 0) {
+    Write-Warning "No job name found. This is likely an error.";
+    return;
+  }
+  else {
+    Write-Output "Multiple job names found '$JobName'.";
+    return;
+  }
+}
+
+$dumpCollectionJob = Get-Job -Name $JobName -ErrorAction SilentlyContinue;
+$registeredJob = Get-ScheduledJob -Name $JobName -ErrorAction SilentlyContinue;
+
+if ($null -eq $dumpCollectionJob) {
+  Write-Output "No job found for '$JobName'. It either didn't run or there is an issue with the job definition.";
+
+  if ($null -eq $registeredJob) {
+    Write-Warning "Couldn't find a scheduled job '$JobName'.";
+  }
+  return;
+}
+
+Write-Output "Listing existing jobs";
+Get-Job -Name CaptureDumps*
+
+Write-Output "Listing existing scheduled jobs";
+Get-ScheduledJob -Name CaptureDumps*
+
+Write-Output "Displaying job output";
+Receive-Job $dumpCollectionJob;
+
+Write-Output "Waiting for current job to finish";
+Get-Job -ErrorAction SilentlyContinue | Wait-Job;
+
+try {
+    Write-Output "Removing collection job";
+    Remove-Job $dumpCollectionJob;
+}
+catch {
+    Write-Output "Failed to remove collection job";
+}
+
+try {
+    Write-Output "Unregistering scheduled job";
+    Unregister-ScheduledJob $registeredJob;
+}
+catch {
+    Write-Output "Failed to unregister $JobName";
+}

+ 46 - 0
eng/scripts/InstallProcDump.ps1

@@ -0,0 +1,46 @@
+<#
+.SYNOPSIS
+    Installs ProcDump into a folder in this repo.
+.DESCRIPTION
+    This script downloads and extracts the ProcDump.
+.PARAMETER Force
+    Overwrite the existing installation
+#>
+param(
+    [switch]$Force
+)
+$ErrorActionPreference = 'Stop'
+$ProgressPreference = 'SilentlyContinue' # Workaround PowerShell/PowerShell#2138
+
+Set-StrictMode -Version 1
+
+$repoRoot = Resolve-Path "$PSScriptRoot\..\.."
+$installDir = "$repoRoot\.tools\ProcDump\"
+$tempDir = "$repoRoot\obj"
+
+if (Test-Path $installDir) {
+    if ($Force) {
+        Remove-Item -Force -Recurse $installDir
+    }
+    else {
+        Write-Host "ProcDump already installed to $installDir. Exiting without action. Call this script again with -Force to overwrite."
+        exit 0
+    }
+}
+
+Remove-Item -Force -Recurse $tempDir -ErrorAction Ignore | out-null
+mkdir $tempDir -ea Ignore | out-null
+mkdir $installDir -ea Ignore | out-null
+Write-Host "Starting ProcDump download"
+Invoke-WebRequest -UseBasicParsing -Uri "https://download.sysinternals.com/files/Procdump.zip" -Out "$tempDir/ProcDump.zip"
+Write-Host "Done downloading ProcDump"
+Expand-Archive "$tempDir/ProcDump.zip" -d "$tempDir/ProcDump/"
+Write-Host "Expanded ProcDump to $tempDir"
+Write-Host "Installing ProcDump to $installDir"
+Move-Item "$tempDir/ProcDump/*" $installDir
+Write-Host "Done installing ProcDump to $installDir"
+
+if ($env:TF_BUILD) {
+    Write-Host "##vso[task.setvariable variable=ProcDumpPath]$installDir"
+    Write-Host "##vso[task.prependpath]$installDir"
+}

+ 123 - 0
eng/scripts/StartDumpCollectionForHangingBuilds.ps1

@@ -0,0 +1,123 @@
+param(
+  [Parameter(Mandatory = $true)]
+  [ValidateNotNullOrEmpty()]
+  [string]
+  $ProcDumpPath,
+  [Parameter(Mandatory = $true)]
+  [ValidateNotNullOrEmpty()]
+  [string]
+  $ProcDumpOutputPath,
+  [Parameter(Mandatory = $true)]
+  [datetime]
+  $WakeTime,
+  [Parameter(Mandatory = $true)]
+  [ValidateNotNullOrEmpty()]
+  [string []]
+  $CandidateProcessNames
+)
+
+Write-Output "Setting up a scheduled job to capture process dumps.";
+
+if ((-not (Test-Path $ProcDumpPath))) {
+  Write-Warning "Can't find ProcDump at '$ProcDumpPath'.";
+}
+else {
+  Write-Output "Using ProcDump from '$ProcDumpPath'.";
+}
+
+try {
+  $previousJobs = Get-Job -Name CaptureDumps* -ErrorAction SilentlyContinue;
+  $previousScheduledJobs = Get-ScheduledJob CaptureDumps* -ErrorAction SilentlyContinue;
+
+  if ($previousJobs.Count -ne 0) {
+    Write-Output "Found existing dump jobs.";
+  }
+
+  if ($previousScheduledJobs.Count -ne 0) {
+    Write-Output "Found existing dump jobs.";
+  }
+
+  $previousJobs | Stop-Job -PassThru | Remove-Job;
+  $previousScheduledJobs | Unregister-ScheduledJob;
+}
+catch {
+  Write-Output "There was an error cleaning up previous jobs.";
+  Write-Output $_.Exception.Message;
+}
+
+$repoRoot = Resolve-Path "$PSScriptRoot\..\..";
+$ProcDumpOutputPath = Join-Path $repoRoot $ProcDumpOutputPath;
+
+Write-Output "Dumps will be placed at '$ProcDumpOutputPath'.";
+Write-Output "Watching processes $($CandidateProcessNames -join ', ')";
+
+# This script registers as a scheduled job. This scheduled job executes after $WakeTime.
+# When the scheduled job executes, it runs procdump on all alive processes whose name matches $CandidateProcessNames.
+# The dumps are placed in $ProcDumpOutputPath
+# If the build completes sucessfully in less than $WakeTime, a final step unregisters the job.
+
+# Create a unique identifier for the job name
+$JobName = "CaptureDumps" + (New-Guid).ToString("N");
+
+# Ensure that the dumps output path exists.
+if ((-not (Test-Path $ProcDumpOutputPath))) {
+  New-Item -ItemType Directory $ProcDumpOutputPath | Out-Null;
+}
+
+# We write a sentinel file that we use at the end of the build to
+# find the job we started and to determine the results from the sheduled
+# job (Whether it ran or not and to display the outputs form the job)
+$sentinelFile = Join-Path $ProcDumpOutputPath "dump-sentinel.txt";
+Out-File -FilePath $sentinelFile -InputObject $JobName | Out-Null;
+
+[scriptblock] $ScriptCode = {
+  param(
+    $ProcDumpPath,
+    $ProcDumpOutputPath,
+    $CandidateProcessNames)
+
+  Write-Output "Waking up to capture process dumps. Determining hanging processes.";
+
+  [System.Diagnostics.Process []]$AliveProcesses = @();
+  foreach ($candidate in $CandidateProcessNames) {
+    try {
+      $candidateProcesses = Get-Process $candidate;
+      $candidateProcesses | ForEach-Object { Write-Output "Found candidate process $candidate with PID '$($_.Id)'." };
+      $AliveProcesses += $candidateProcesses;
+    }
+    catch {
+      Write-Output "No process found for $candidate";
+    }
+  }
+
+  Write-Output "Starting process dump capture.";
+
+  $dumpFullPath = [System.IO.Path]::Combine($ProcDumpOutputPath, "hung_PROCESSNAME_PID_YYMMDD_HHMMSS.dmp");
+
+  Write-Output "Capturing output for $($AliveProcesses.Length) processes.";
+
+  foreach ($process in $AliveProcesses) {
+
+    $procDumpArgs = @("-accepteula", "-ma", $process.Id, $dumpFullPath);
+    try {
+      Write-Output "Capturing dump for dump for '$($process.Name)' with PID '$($process.Id)'.";
+      Start-Process -FilePath $ProcDumpPath -ArgumentList $procDumpArgs -NoNewWindow -Wait;
+    }
+    catch {
+      Write-Output "There was an error capturing a process dump for '$($process.Name)' with PID '$($process.Id)'."
+      Write-Warning $_.Exception.Message;
+    }
+  }
+
+  Write-Output "Done capturing process dumps.";
+}
+
+$ScriptTrigger = New-JobTrigger -Once -At $WakeTime;
+
+try {
+  Register-ScheduledJob -Name $JobName -ScriptBlock $ScriptCode -Trigger $ScriptTrigger -ArgumentList $ProcDumpPath, $ProcDumpOutputPath, $CandidateProcessNames;
+}
+catch {
+  Write-Warning "Failed to register scheduled job '$JobName'. Dumps will not be captured for build hangs.";
+  Write-Warning $_.Exception.Message;
+}

+ 1 - 1
eng/scripts/ci-source-build.sh

@@ -15,4 +15,4 @@ export DotNetBuildFromSource='true'
 "$reporoot/eng/common/build.sh" --restore --build --ci --configuration Release /p:ProjectToBuild=$reporoot/eng/tools/RepoTasks/RepoTasks.csproj
 
  # Build projects
-"$reporoot/eng/common/build.sh" --restore --build --pack "$@"
+"$reporoot/eng/common/build.sh" --restore --build --pack "$@"

+ 0 - 38
eng/tools/Maestro/Maestro.csproj

@@ -1,38 +0,0 @@
-<Project Sdk="Microsoft.NET.Sdk">
-
-  <PropertyGroup>
-    <!-- TFM doesn't matter. These settings are required to make NuGet happy so we can restore required MSBuild packages. -->
-    <TargetFramework>$(DefaultNetCoreTargetFramework)</TargetFramework>
-    <DisableImplicitFrameworkReferences>true</DisableImplicitFrameworkReferences>
-    <ManifestsPath>$(ArtifactsDir)manifests\</ManifestsPath>
-    <DisablePackageReferenceRestrictions>true</DisablePackageReferenceRestrictions>
-  </PropertyGroup>
-
-  <ItemGroup>
-    <PackageReference Include="Microsoft.DotNet.Build.Tasks.Feed" Version="2.2.0-beta.19061.6" />
-  </ItemGroup>
-
-  <Target Name="GetFilesToPublish">
-    <ItemGroup>
-      <PackageToPublish Include="$(ArtifactsShippingPackagesDir)*.nupkg" />
-      <PackageToPublish Include="$(ArtifactsNonShippingPackagesDir)*.nupkg">
-        <!-- 'NonShipping' packages are used to transfer bits to partner teams, and should not be used by customers. -->
-        <ManifestArtifactData>NonShipping=true</ManifestArtifactData>
-      </PackageToPublish>
-    </ItemGroup>
-  </Target>
-
-  <Target Name="GenerateBuildAssetManifest"
-          DependsOnTargets="GetFilesToPublish">
-
-    <GenerateBuildManifest
-      Artifacts="@(PackageToPublish)"
-      OutputPath="$(ManifestsPath)aspnetcore-$(TargetRuntimeIdentifier)-$(PackageVersion).xml"
-      BuildId="$(PackageVersion)"
-      BuildData="Location=https://dotnetfeed.blob.core.windows.net/aspnet-aspnetcore/index.json"
-      RepoUri="$(RepositoryUrl)"
-      RepoBranch="$(BUILD_SOURCEBRANCH)"
-      RepoCommit="$(BUILD_SOURCEVERSION)" />
-  </Target>
-
-</Project>

+ 0 - 38
eng/tools/XplatPackageSigner/XplatPackageSigner.proj

@@ -1,38 +0,0 @@
-<!--
-  Code signing of .nupkg's built on Linux/macOS cannot be code-signed on the same machine which built the package.
-  This project takes as inputs a folder of *.nupkg packages and code signs them using MicroBuild.
-
-  Note: because Authenticode signing of .dll's is not something Linux and macOS can verify anyways, this signing
-  process only code-signs the .nupkg itself, not the contents.
--->
-<Project DefaultTargets="Build" InitialTargets="CheckForRequiredProperties">
-  <PropertyGroup>
-    <SignType>$([MSBuild]::ValueOrDefault($(SignType),'real'))</SignType>
-  </PropertyGroup>
-
-  <Import Project="..\..\..\Directory.Build.props" />
-  <Import Project="..\..\targets\MicroBuild.Plugin.props" Condition="'$(MicroBuildSentinelFile)' == ''" />
-  <Import Project="$(MicroBuildPluginDirectory)\MicroBuild.Plugins.*\**\build\MicroBuild.Plugins.*.props" Condition=" '$(MicroBuildPluginDirectory)' != ''" />
-
-  <PropertyGroup Condition="'$(DirectoryToSign)' != ''">
-    <OutDir>$([MSBuild]::NormalizeDirectory($(DirectoryToSign)))</OutDir>
-    <IntermediateOutputPath>$(BaseIntermediateOutputPath)</IntermediateOutputPath>
-  </PropertyGroup>
-
-  <ItemGroup Condition="'$(OutDir)' != ''">
-    <SymbolsPackages Include="$(OutDir)**\*.symbols.nupkg" />
-    <FilesToSign Include="$(OutDir)**\*.nupkg">
-      <Authenticode>NuGet</Authenticode>
-    </FilesToSign>
-  </ItemGroup>
-
-  <Target Name="CheckForRequiredProperties">
-    <Error Text="Missing required property: DirectoryToSign" Condition="'$(DirectoryToSign)' == ''"/>
-    <Error Text="Could not find any packages to sign in $(DirectoryToSign)" Condition="@(FilesToSign->Count()) == 0"/>
-  </Target>
-
-  <!-- MicroBuild code-signing chains onto this target. -->
-  <Target Name="AfterBuild" />
-  <Target Name="Build" DependsOnTargets="AfterBuild" />
-  <Import Project="$(MicroBuildPluginDirectory)\MicroBuild.Plugins.*\**\build\MicroBuild.Plugins.*.targets" Condition=" '$(MicroBuildPluginDirectory)' != ''" />
-</Project>

+ 0 - 15
eng/tools/XplatPackageSigner/sign-packages.cmd

@@ -1,15 +0,0 @@
-@ECHO OFF
-
-SET DirToSign=%1
-
-IF "%DirToSign%"=="" (
-    echo Error^: Expected argument ^<DirToSign^>
-    echo Usage^: sign-packages.cmd ^<DirToSign^>
-
-    exit /b 1
-)
-
-SET RepoRoot=%~dp0..\..\..
-SET Project=%~dp0XplatPackageSigner.proj
-
-%RepoRoot%\build.cmd -NoRestore -projects %project% /p:DirectoryToSign=%DirToSign% /bl:%RepoRoot%\artifacts\log\XplatSign.binlog

+ 2 - 2
global.json

@@ -24,7 +24,7 @@
   },
   "msbuild-sdks": {
     "Yarn.MSBuild": "1.15.2",
-    "Microsoft.DotNet.Arcade.Sdk": "1.0.0-beta.19425.1",
-    "Microsoft.DotNet.Helix.Sdk": "2.0.0-beta.19425.1"
+    "Microsoft.DotNet.Arcade.Sdk": "1.0.0-beta.19462.4",
+    "Microsoft.DotNet.Helix.Sdk": "2.0.0-beta.19462.4"
   }
 }

+ 5 - 0
src/Analyzers/shared/FeatureDetection/Microsoft.AspNetCore.Analyzers.FeatureDetection.Sources.csproj

@@ -22,6 +22,11 @@
   </PropertyGroup>
 
   <ItemGroup>
+    <None Include="lib\**\*">
+      <Pack>True</Pack>
+      <PackagePath>lib</PackagePath>
+    </None>
+
     <Compile Include="$(MSBuildProjectDirectory)\**\*.cs" Exclude="$(DefaultExcludeItems)">
       <Pack>true</Pack>
       <PackagePath>$(ContentTargetFolders)\cs\netstandard1.0\shared\</PackagePath>

+ 0 - 0
src/Analyzers/shared/FeatureDetection/lib/netstandard1.0/_._


+ 1 - 0
src/Antiforgery/src/Microsoft.AspNetCore.Antiforgery.csproj

@@ -6,6 +6,7 @@
     <IsAspNetCoreApp>true</IsAspNetCoreApp>
     <GenerateDocumentationFile>true</GenerateDocumentationFile>
     <PackageTags>aspnetcore;antiforgery</PackageTags>
+    <IsShippingPackage>false</IsShippingPackage>
   </PropertyGroup>
 
   <ItemGroup>

+ 2 - 1
src/Components/Authorization/src/CascadingAuthenticationState.razor

@@ -9,7 +9,8 @@
     /// <summary>
     /// The content to which the authentication state should be provided.
     /// </summary>
-    [Parameter] public RenderFragment ChildContent { get; set; }
+    [Parameter]
+    public RenderFragment ChildContent { get; set; }
 
     protected override void OnInitialized()
     {

+ 0 - 9
src/Components/Blazor/Directory.Build.props

@@ -1,9 +0,0 @@
-<Project>
-  <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory)..\, Directory.Build.props))\Directory.Build.props" />
-
-  <PropertyGroup>
-    <!-- Override prerelease label and use preview 9, even in the final build -->
-    <PreReleaseVersionLabel>$(BlazorClientPreReleaseVersionLabel)</PreReleaseVersionLabel>
-    <DotNetFinalVersionKind></DotNetFinalVersionKind>
-  </PropertyGroup>
-</Project>

+ 0 - 2
src/Components/Blazor/Templates/src/content/BlazorWasm-CSharp/Client/BlazorWasm-CSharp.Client.csproj

@@ -2,8 +2,6 @@
 
   <PropertyGroup>
     <TargetFramework>netstandard2.0</TargetFramework>
-    <OutputType>Exe</OutputType>
-    <LangVersion>7.3</LangVersion>
     <RazorLangVersion>3.0</RazorLangVersion>
   </PropertyGroup>
 

+ 2 - 2
src/Components/Blazor/Templates/src/content/BlazorWasm-CSharp/Client/Pages/Counter.razor

@@ -7,9 +7,9 @@
 <button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
 
 @code {
-    int currentCount = 0;
+    private int currentCount = 0;
 
-    void IncrementCount()
+    private void IncrementCount()
     {
         currentCount++;
     }

+ 2 - 2
src/Components/Blazor/Templates/src/content/BlazorWasm-CSharp/Client/Pages/FetchData.razor

@@ -38,7 +38,7 @@ else
 }
 
 @code {
-    WeatherForecast[] forecasts;
+    private WeatherForecast[] forecasts;
 
     protected override async Task OnInitializedAsync()
     {
@@ -60,5 +60,5 @@ else
 
         public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
     }
-     #endif*@
+    #endif*@
 }

+ 3 - 3
src/Components/Blazor/Templates/src/content/BlazorWasm-CSharp/Client/Shared/NavMenu.razor

@@ -26,11 +26,11 @@
 </div>
 
 @code {
-    bool collapseNavMenu = true;
+    private bool collapseNavMenu = true;
 
-    string NavMenuCssClass => collapseNavMenu ? "collapse" : null;
+    private string NavMenuCssClass => collapseNavMenu ? "collapse" : null;
 
-    void ToggleNavMenu()
+    private void ToggleNavMenu()
     {
         collapseNavMenu = !collapseNavMenu;
     }

+ 2 - 1
src/Components/Blazor/Templates/src/content/BlazorWasm-CSharp/Client/Shared/SurveyPrompt.razor

@@ -11,5 +11,6 @@
 
 @code {
     // Demonstrates how a parent component can supply parameters
-    [Parameter] public string Title { get; set; }
+    [Parameter]
+    public string Title { get; set; }
 }

+ 0 - 1
src/Components/Blazor/Templates/src/content/BlazorWasm-CSharp/Server/BlazorWasm-CSharp.Server.csproj

@@ -7,7 +7,6 @@
 
   <ItemGroup>
     <PackageReference Include="Microsoft.AspNetCore.Blazor.Server" Version="$(TemplateBlazorPackageVersion)" />
-    <PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="$(TemplateComponentsPackageVersion)" />
   </ItemGroup>
 
   <ItemGroup>

+ 1 - 2
src/Components/Blazor/Templates/src/content/BlazorWasm-CSharp/Server/Startup.cs

@@ -3,7 +3,6 @@ using Microsoft.AspNetCore.Hosting;
 using Microsoft.AspNetCore.ResponseCompression;
 using Microsoft.Extensions.DependencyInjection;
 using Microsoft.Extensions.Hosting;
-using Newtonsoft.Json.Serialization;
 using System.Linq;
 
 namespace BlazorWasm_CSharp.Server
@@ -14,7 +13,7 @@ namespace BlazorWasm_CSharp.Server
         // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
         public void ConfigureServices(IServiceCollection services)
         {
-            services.AddMvc().AddNewtonsoftJson();
+            services.AddMvc();
             services.AddResponseCompression(opts =>
             {
                 opts.MimeTypes = ResponseCompressionDefaults.MimeTypes.Concat(

+ 2 - 1
src/Components/Blazor/testassets/HostedInAspNet.Server/HostedInAspNet.Server.csproj

@@ -1,4 +1,4 @@
-<Project Sdk="Microsoft.NET.Sdk.Web">
+<Project Sdk="Microsoft.NET.Sdk.Web">
 
   <PropertyGroup>
     <TargetFramework>$(DefaultNetCoreTargetFramework)</TargetFramework>
@@ -11,6 +11,7 @@
   <ItemGroup>
     <Reference Include="Microsoft.AspNetCore.Blazor.Server" />
     <Reference Include="Microsoft.AspNetCore" />
+    <Reference Include="Microsoft.Extensions.Hosting" />
   </ItemGroup>
 
 </Project>

+ 9 - 10
src/Components/Blazor/testassets/HostedInAspNet.Server/Program.cs

@@ -1,9 +1,8 @@
-// Copyright (c) .NET Foundation. All rights reserved.
+// Copyright (c) .NET Foundation. All rights reserved.
 // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
 
-using Microsoft.AspNetCore;
 using Microsoft.AspNetCore.Hosting;
-using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.Hosting;
 
 namespace HostedInAspNet.Server
 {
@@ -14,12 +13,12 @@ namespace HostedInAspNet.Server
             BuildWebHost(args).Run();
         }
 
-        public static IWebHost BuildWebHost(string[] args) =>
-            WebHost.CreateDefaultBuilder(args)
-                .UseConfiguration(new ConfigurationBuilder()
-                    .AddCommandLine(args)
-                    .Build())
-                .UseStartup<Startup>()
-                .Build();
+        public static IHost BuildWebHost(string[] args) =>
+            Host.CreateDefaultBuilder(args)
+            .ConfigureWebHostDefaults(webHostBuilder =>
+            {
+                webHostBuilder.UseStartup<Startup>();
+            })
+            .Build();
     }
 }

+ 2 - 1
src/Components/Blazor/testassets/MonoSanity/MonoSanity.csproj

@@ -1,4 +1,4 @@
-<Project Sdk="Microsoft.NET.Sdk.Web">
+<Project Sdk="Microsoft.NET.Sdk.Web">
 
   <PropertyGroup>
     <TargetFramework>$(DefaultNetCoreTargetFramework)</TargetFramework>
@@ -11,6 +11,7 @@
   <ItemGroup>
     <Reference Include="Microsoft.AspNetCore" />
     <Reference Include="Microsoft.AspNetCore.Blazor.Server" />
+    <Reference Include="Microsoft.Extensions.Hosting" />
   </ItemGroup>
 
 </Project>

+ 9 - 10
src/Components/Blazor/testassets/MonoSanity/Program.cs

@@ -1,9 +1,8 @@
-// Copyright (c) .NET Foundation. All rights reserved.
+// Copyright (c) .NET Foundation. All rights reserved.
 // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
 
-using Microsoft.AspNetCore;
 using Microsoft.AspNetCore.Hosting;
-using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.Hosting;
 
 namespace MonoSanity
 {
@@ -14,12 +13,12 @@ namespace MonoSanity
             BuildWebHost(args).Run();
         }
 
-        public static IWebHost BuildWebHost(string[] args) =>
-            WebHost.CreateDefaultBuilder(args)
-                .UseConfiguration(new ConfigurationBuilder()
-                    .AddCommandLine(args)
-                    .Build())
-                .UseStartup<Startup>()
-                .Build();
+        public static IHost BuildWebHost(string[] args) =>
+            Host.CreateDefaultBuilder(args)
+            .ConfigureWebHostDefaults(webHostBuilder =>
+            {
+                webHostBuilder.UseStartup<Startup>();
+            })
+            .Build();
     }
 }

+ 36 - 34
src/Components/Components.sln

@@ -65,10 +65,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "testassets", "testassets",
 EndProject
 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BasicTestApp", "test\testassets\BasicTestApp\BasicTestApp.csproj", "{4C5AB32A-3C7E-4A55-96A7-1F5248CFE929}"
 EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ComponentsApp.App", "test\testassets\ComponentsApp.App\ComponentsApp.App.csproj", "{AF2BADF8-DA1F-4D5E-ADC2-69C7F7E7C41C}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ComponentsApp.Server", "test\testassets\ComponentsApp.Server\ComponentsApp.Server.csproj", "{AD99C80B-CF2D-47D1-BBA0-BEF18BAEAD35}"
-EndProject
 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestContentPackage", "test\testassets\TestContentPackage\TestContentPackage.csproj", "{423CCF23-C0B4-4D21-896C-16DC98689DB5}"
 EndProject
 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Components.TestServer", "test\testassets\TestServer\Components.TestServer.csproj", "{D6AEB328-EBC0-40B1-8936-301597883DFA}"
@@ -214,9 +210,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Signal
 EndProject
 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Http.Connections.Client", "..\SignalR\clients\csharp\Http.Connections.Client\src\Microsoft.AspNetCore.Http.Connections.Client.csproj", "{F88118E1-6F4A-4F89-B047-5FFD2889B9F0}"
 EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ignitor", "test\testassets\Ignitor\Ignitor.csproj", "{A78CE874-76B7-46FE-8009-1ED5258BA0AA}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ignitor", "Ignitor\src\Ignitor.csproj", "{A78CE874-76B7-46FE-8009-1ED5258BA0AA}"
 EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ignitor.Test", "test\Ignitor.Test\Ignitor.Test.csproj", "{FC2A1EB0-A116-4689-92B7-239B1DCCF4CA}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ignitor.Test", "Ignitor\test\Ignitor.Test.csproj", "{FC2A1EB0-A116-4689-92B7-239B1DCCF4CA}"
 EndProject
 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Blazor.HttpClient", "Blazor\Http\src\Microsoft.AspNetCore.Blazor.HttpClient.csproj", "{74D21785-2FAB-4266-B7C4-E311EC8EE0DF}"
 EndProject
@@ -236,6 +232,12 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Compon
 EndProject
 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Components.Forms.Tests", "Forms\test\Microsoft.AspNetCore.Components.Forms.Tests.csproj", "{173D84A3-0F37-480F-AC0F-7E2DBBE32B28}"
 EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Samples", "Samples", "{46E4300C-5726-4108-B9A2-18BB94EB26ED}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.HttpsPolicy", "..\Middleware\HttpsPolicy\src\Microsoft.AspNetCore.HttpsPolicy.csproj", "{4664276D-606A-4BB3-873A-9EE84FB22877}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BlazorServerApp", "Samples\BlazorServerApp\BlazorServerApp.csproj", "{BBF37AF9-8290-4B70-8BA8-0F6017B3B620}"
+EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|Any CPU = Debug|Any CPU
@@ -522,30 +524,6 @@ Global
 		{4C5AB32A-3C7E-4A55-96A7-1F5248CFE929}.Release|x64.Build.0 = Release|Any CPU
 		{4C5AB32A-3C7E-4A55-96A7-1F5248CFE929}.Release|x86.ActiveCfg = Release|Any CPU
 		{4C5AB32A-3C7E-4A55-96A7-1F5248CFE929}.Release|x86.Build.0 = Release|Any CPU
-		{AF2BADF8-DA1F-4D5E-ADC2-69C7F7E7C41C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{AF2BADF8-DA1F-4D5E-ADC2-69C7F7E7C41C}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{AF2BADF8-DA1F-4D5E-ADC2-69C7F7E7C41C}.Debug|x64.ActiveCfg = Debug|Any CPU
-		{AF2BADF8-DA1F-4D5E-ADC2-69C7F7E7C41C}.Debug|x64.Build.0 = Debug|Any CPU
-		{AF2BADF8-DA1F-4D5E-ADC2-69C7F7E7C41C}.Debug|x86.ActiveCfg = Debug|Any CPU
-		{AF2BADF8-DA1F-4D5E-ADC2-69C7F7E7C41C}.Debug|x86.Build.0 = Debug|Any CPU
-		{AF2BADF8-DA1F-4D5E-ADC2-69C7F7E7C41C}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{AF2BADF8-DA1F-4D5E-ADC2-69C7F7E7C41C}.Release|Any CPU.Build.0 = Release|Any CPU
-		{AF2BADF8-DA1F-4D5E-ADC2-69C7F7E7C41C}.Release|x64.ActiveCfg = Release|Any CPU
-		{AF2BADF8-DA1F-4D5E-ADC2-69C7F7E7C41C}.Release|x64.Build.0 = Release|Any CPU
-		{AF2BADF8-DA1F-4D5E-ADC2-69C7F7E7C41C}.Release|x86.ActiveCfg = Release|Any CPU
-		{AF2BADF8-DA1F-4D5E-ADC2-69C7F7E7C41C}.Release|x86.Build.0 = Release|Any CPU
-		{AD99C80B-CF2D-47D1-BBA0-BEF18BAEAD35}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{AD99C80B-CF2D-47D1-BBA0-BEF18BAEAD35}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{AD99C80B-CF2D-47D1-BBA0-BEF18BAEAD35}.Debug|x64.ActiveCfg = Debug|Any CPU
-		{AD99C80B-CF2D-47D1-BBA0-BEF18BAEAD35}.Debug|x64.Build.0 = Debug|Any CPU
-		{AD99C80B-CF2D-47D1-BBA0-BEF18BAEAD35}.Debug|x86.ActiveCfg = Debug|Any CPU
-		{AD99C80B-CF2D-47D1-BBA0-BEF18BAEAD35}.Debug|x86.Build.0 = Debug|Any CPU
-		{AD99C80B-CF2D-47D1-BBA0-BEF18BAEAD35}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{AD99C80B-CF2D-47D1-BBA0-BEF18BAEAD35}.Release|Any CPU.Build.0 = Release|Any CPU
-		{AD99C80B-CF2D-47D1-BBA0-BEF18BAEAD35}.Release|x64.ActiveCfg = Release|Any CPU
-		{AD99C80B-CF2D-47D1-BBA0-BEF18BAEAD35}.Release|x64.Build.0 = Release|Any CPU
-		{AD99C80B-CF2D-47D1-BBA0-BEF18BAEAD35}.Release|x86.ActiveCfg = Release|Any CPU
-		{AD99C80B-CF2D-47D1-BBA0-BEF18BAEAD35}.Release|x86.Build.0 = Release|Any CPU
 		{423CCF23-C0B4-4D21-896C-16DC98689DB5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{423CCF23-C0B4-4D21-896C-16DC98689DB5}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{423CCF23-C0B4-4D21-896C-16DC98689DB5}.Debug|x64.ActiveCfg = Debug|Any CPU
@@ -1482,6 +1460,30 @@ Global
 		{173D84A3-0F37-480F-AC0F-7E2DBBE32B28}.Release|x64.Build.0 = Release|Any CPU
 		{173D84A3-0F37-480F-AC0F-7E2DBBE32B28}.Release|x86.ActiveCfg = Release|Any CPU
 		{173D84A3-0F37-480F-AC0F-7E2DBBE32B28}.Release|x86.Build.0 = Release|Any CPU
+		{4664276D-606A-4BB3-873A-9EE84FB22877}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{4664276D-606A-4BB3-873A-9EE84FB22877}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{4664276D-606A-4BB3-873A-9EE84FB22877}.Debug|x64.ActiveCfg = Debug|Any CPU
+		{4664276D-606A-4BB3-873A-9EE84FB22877}.Debug|x64.Build.0 = Debug|Any CPU
+		{4664276D-606A-4BB3-873A-9EE84FB22877}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{4664276D-606A-4BB3-873A-9EE84FB22877}.Debug|x86.Build.0 = Debug|Any CPU
+		{4664276D-606A-4BB3-873A-9EE84FB22877}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{4664276D-606A-4BB3-873A-9EE84FB22877}.Release|Any CPU.Build.0 = Release|Any CPU
+		{4664276D-606A-4BB3-873A-9EE84FB22877}.Release|x64.ActiveCfg = Release|Any CPU
+		{4664276D-606A-4BB3-873A-9EE84FB22877}.Release|x64.Build.0 = Release|Any CPU
+		{4664276D-606A-4BB3-873A-9EE84FB22877}.Release|x86.ActiveCfg = Release|Any CPU
+		{4664276D-606A-4BB3-873A-9EE84FB22877}.Release|x86.Build.0 = Release|Any CPU
+		{BBF37AF9-8290-4B70-8BA8-0F6017B3B620}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{BBF37AF9-8290-4B70-8BA8-0F6017B3B620}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{BBF37AF9-8290-4B70-8BA8-0F6017B3B620}.Debug|x64.ActiveCfg = Debug|Any CPU
+		{BBF37AF9-8290-4B70-8BA8-0F6017B3B620}.Debug|x64.Build.0 = Debug|Any CPU
+		{BBF37AF9-8290-4B70-8BA8-0F6017B3B620}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{BBF37AF9-8290-4B70-8BA8-0F6017B3B620}.Debug|x86.Build.0 = Debug|Any CPU
+		{BBF37AF9-8290-4B70-8BA8-0F6017B3B620}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{BBF37AF9-8290-4B70-8BA8-0F6017B3B620}.Release|Any CPU.Build.0 = Release|Any CPU
+		{BBF37AF9-8290-4B70-8BA8-0F6017B3B620}.Release|x64.ActiveCfg = Release|Any CPU
+		{BBF37AF9-8290-4B70-8BA8-0F6017B3B620}.Release|x64.Build.0 = Release|Any CPU
+		{BBF37AF9-8290-4B70-8BA8-0F6017B3B620}.Release|x86.ActiveCfg = Release|Any CPU
+		{BBF37AF9-8290-4B70-8BA8-0F6017B3B620}.Release|x86.Build.0 = Release|Any CPU
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE
@@ -1512,8 +1514,6 @@ Global
 		{B998B96D-E3CD-440E-9BFD-8F4EDC9D6732} = {E9E9CF3C-CE9B-4282-B2BB-97EFC3872798}
 		{44E0D4F3-4430-4175-B482-0D1AEE4BB699} = {E9E9CF3C-CE9B-4282-B2BB-97EFC3872798}
 		{4C5AB32A-3C7E-4A55-96A7-1F5248CFE929} = {44E0D4F3-4430-4175-B482-0D1AEE4BB699}
-		{AF2BADF8-DA1F-4D5E-ADC2-69C7F7E7C41C} = {44E0D4F3-4430-4175-B482-0D1AEE4BB699}
-		{AD99C80B-CF2D-47D1-BBA0-BEF18BAEAD35} = {44E0D4F3-4430-4175-B482-0D1AEE4BB699}
 		{423CCF23-C0B4-4D21-896C-16DC98689DB5} = {44E0D4F3-4430-4175-B482-0D1AEE4BB699}
 		{D6AEB328-EBC0-40B1-8936-301597883DFA} = {44E0D4F3-4430-4175-B482-0D1AEE4BB699}
 		{6BA2DCAA-CB68-4AE2-BBBE-746A728D30E0} = {2FC10057-7A0A-4E34-8302-879925BC0102}
@@ -1583,8 +1583,8 @@ Global
 		{DA137BD4-F7F1-4D53-855F-5EC40CEA36B0} = {2FC10057-7A0A-4E34-8302-879925BC0102}
 		{0CDAB70B-71DC-43BE-ACB7-AD2EE3541FFB} = {2FC10057-7A0A-4E34-8302-879925BC0102}
 		{F88118E1-6F4A-4F89-B047-5FFD2889B9F0} = {2FC10057-7A0A-4E34-8302-879925BC0102}
-		{A78CE874-76B7-46FE-8009-1ED5258BA0AA} = {44E0D4F3-4430-4175-B482-0D1AEE4BB699}
-		{FC2A1EB0-A116-4689-92B7-239B1DCCF4CA} = {E9E9CF3C-CE9B-4282-B2BB-97EFC3872798}
+		{A78CE874-76B7-46FE-8009-1ED5258BA0AA} = {D6712550-0DA2-49C8-88E1-F04CAB982BF4}
+		{FC2A1EB0-A116-4689-92B7-239B1DCCF4CA} = {D6712550-0DA2-49C8-88E1-F04CAB982BF4}
 		{74D21785-2FAB-4266-B7C4-E311EC8EE0DF} = {7260DED9-22A9-4E9D-92F4-5E8A4404DEAF}
 		{E4C01A3F-D3C1-4639-A6A9-930E918843DD} = {7260DED9-22A9-4E9D-92F4-5E8A4404DEAF}
 		{DE297C91-B3E9-4C6F-B74D-0AF9EFEBF684} = {A27FF193-195B-4474-8E6C-840B2E339373}
@@ -1592,6 +1592,8 @@ Global
 		{B13CDE69-ED22-4664-AAD7-686ED8CD5E88} = {08791FEE-761D-40EF-B701-1D31FD1E6E53}
 		{A5C132FB-1E03-4DA9-8D05-80755ED1D0ED} = {B0EEB429-4C8C-42AA-8822-3058E7DBC98F}
 		{173D84A3-0F37-480F-AC0F-7E2DBBE32B28} = {B0EEB429-4C8C-42AA-8822-3058E7DBC98F}
+		{4664276D-606A-4BB3-873A-9EE84FB22877} = {2FC10057-7A0A-4E34-8302-879925BC0102}
+		{BBF37AF9-8290-4B70-8BA8-0F6017B3B620} = {46E4300C-5726-4108-B9A2-18BB94EB26ED}
 	EndGlobalSection
 	GlobalSection(ExtensibilityGlobals) = postSolution
 		SolutionGuid = {CC3C47E1-AD1A-4619-9CD3-E08A0148E5CE}

+ 3 - 4
src/Components/Components/src/Microsoft.AspNetCore.Components.csproj

@@ -38,16 +38,15 @@
   <!-- Pack settings -->
   <PropertyGroup>
     <NuspecFile>Microsoft.AspNetCore.Components.multitarget.nuspec</NuspecFile>
-    <NuspecFile Condition="'$(DotNetBuildFromSource)' == 'true'">Microsoft.AspNetCore.Components.$(DefaultNetCoreTargetFramework).nuspec</NuspecFile>
+    <NuspecFile Condition="'$(DotNetBuildFromSource)' == 'true'">Microsoft.AspNetCore.Components.netcoreapp.nuspec</NuspecFile>
     <GenerateNuspecDependsOn>$(GenerateNuspecDependsOn);_GetNuspecDependencyPackageVersions</GenerateNuspecDependsOn>
   </PropertyGroup>
 
   <ItemGroup>
     <NuspecProperty Include="jsInteropPackageVersion=$(MicrosoftJSInteropPackageVersion)" />
     <NuspecProperty Condition="'$(DotNetBuildFromSource)' != 'true'" Include="systemComponentModelAnnotationsPackageVersion=$(SystemComponentModelAnnotationsPackageVersion)" />
-    <NuspecProperty Include="OutputBinary=$(MSBuildProjectDirectory)\$(OutputPath)**\$(AssemblyName).dll" />
-    <NuspecProperty Include="OutputSymbol=$(MSBuildProjectDirectory)\$(OutputPath)**\$(AssemblyName).pdb" />
-    <NuspecProperty Include="OutputDocumentation=$(MSBuildProjectDirectory)\$(OutputPath)**\$(AssemblyName).xml" />
+    <NuspecProperty Include="AssemblyName=$(AssemblyName)" />
+    <NuspecProperty Include="OutputPath=$(OutputPath)" />
   </ItemGroup>
 
 </Project>

+ 3 - 3
src/Components/Components/src/Microsoft.AspNetCore.Components.multitarget.nuspec

@@ -17,9 +17,9 @@
     </dependencies>
   </metadata>
   <files>
-    <file src="$OutputBinary$" target="lib\" />
-    <file src="$OutputDocumentation$" target="lib\" />
-    <file src="$OutputSymbol$" target="lib\" />
+    <file src="$OutputPath$**\$AssemblyName$.dll" target="lib\" />
+    <file src="$OutputPath$**\$AssemblyName$.pdb" target="lib\" />
+    <file src="$OutputPath$**\$AssemblyName$.xml" target="lib\" />
     <file src="..\..\THIRD-PARTY-NOTICES.txt" target=".\THIRD-PARTY-NOTICES.txt" />
   </files>
 </package>

+ 3 - 3
src/Components/Components/src/Microsoft.AspNetCore.Components.netcoreapp5.0.nuspec → src/Components/Components/src/Microsoft.AspNetCore.Components.netcoreapp.nuspec

@@ -11,9 +11,9 @@
     </dependencies>
   </metadata>
   <files>
-    <file src="$OutputBinary$" target="lib\" />
-    <file src="$OutputDocumentation$" target="lib\" />
-    <file src="$OutputSymbol$" target="lib\" />
+    <file src="$OutputPath$**\$AssemblyName$.dll" target="lib\" />
+    <file src="$OutputPath$**\$AssemblyName$.pdb" target="lib\" />
+    <file src="$OutputPath$**\$AssemblyName$.xml" target="lib\" />
     <file src="..\..\THIRD-PARTY-NOTICES.txt" target=".\THIRD-PARTY-NOTICES.txt" />
   </files>
 </package>

+ 0 - 2
src/Components/Components/src/Properties/AssemblyInfo.cs

@@ -7,5 +7,3 @@ using System.Runtime.CompilerServices;
 [assembly: InternalsVisibleTo("Microsoft.AspNetCore.Components.Server.Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
 [assembly: InternalsVisibleTo("Microsoft.AspNetCore.Components.Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
 [assembly: InternalsVisibleTo("Microsoft.AspNetCore.Components.Web.Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
-[assembly: InternalsVisibleTo("Ignitor, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
-[assembly: InternalsVisibleTo("Ignitor.Test, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]

+ 4 - 0
src/Components/Components/src/RenderTree/ArrayBuilderExtensions.cs

@@ -3,7 +3,11 @@
 
 using System;
 
+#if IGNITOR
+namespace Ignitor
+#else
 namespace Microsoft.AspNetCore.Components.RenderTree
+#endif
 {
     internal static class ArrayBuilderExtensions
     {

+ 4 - 0
src/Components/Components/src/RenderTree/ArrayBuilderSegment.cs

@@ -5,7 +5,11 @@ using System;
 using System.Collections;
 using System.Collections.Generic;
 
+#if IGNITOR
+namespace Ignitor
+#else
 namespace Microsoft.AspNetCore.Components.RenderTree
+#endif
 {
     /// <summary>
     /// Types in the Microsoft.AspNetCore.Components.RenderTree are not recommended for use outside

+ 4 - 0
src/Components/Components/src/RenderTree/ArrayRange.cs

@@ -1,7 +1,11 @@
 // Copyright (c) .NET Foundation. All rights reserved.
 // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
 
+#if IGNITOR
+namespace Ignitor
+#else
 namespace Microsoft.AspNetCore.Components.RenderTree
+#endif
 {
     /// <summary>
     /// Types in the Microsoft.AspNetCore.Components.RenderTree are not recommended for use outside

+ 4 - 0
src/Components/Components/src/RenderTree/RenderBatch.cs

@@ -1,7 +1,11 @@
 // Copyright (c) .NET Foundation. All rights reserved.
 // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
 
+#if IGNITOR
+namespace Ignitor
+#else
 namespace Microsoft.AspNetCore.Components.RenderTree
+#endif
 {
     /// <summary>
     /// Types in the Microsoft.AspNetCore.Components.RenderTree are not recommended for use outside

+ 4 - 0
src/Components/Components/src/RenderTree/RenderTreeDiff.cs

@@ -1,7 +1,11 @@
 // Copyright (c) .NET Foundation. All rights reserved.
 // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
 
+#if IGNITOR
+namespace Ignitor
+#else
 namespace Microsoft.AspNetCore.Components.RenderTree
+#endif
 {
     /// <summary>
     /// Types in the Microsoft.AspNetCore.Components.RenderTree are not recommended for use outside

+ 4 - 0
src/Components/Components/src/RenderTree/RenderTreeEdit.cs

@@ -3,7 +3,11 @@
 
 using System.Runtime.InteropServices;
 
+#if IGNITOR
+namespace Ignitor
+#else
 namespace Microsoft.AspNetCore.Components.RenderTree
+#endif
 {
     /// <summary>
     /// Types in the Microsoft.AspNetCore.Components.RenderTree are not recommended for use outside

+ 4 - 0
src/Components/Components/src/RenderTree/RenderTreeEditType.cs

@@ -1,7 +1,11 @@
 // Copyright (c) .NET Foundation. All rights reserved.
 // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
 
+#if IGNITOR
+namespace Ignitor
+#else
 namespace Microsoft.AspNetCore.Components.RenderTree
+#endif
 {
     /// <summary>
     /// Types in the Microsoft.AspNetCore.Components.RenderTree are not recommended for use outside

+ 6 - 0
src/Components/Components/src/RenderTree/RenderTreeFrame.cs

@@ -3,9 +3,15 @@
 
 using System;
 using System.Runtime.InteropServices;
+#if !IGNITOR
 using Microsoft.AspNetCore.Components.Rendering;
+#endif
 
+#if IGNITOR
+namespace Ignitor
+#else
 namespace Microsoft.AspNetCore.Components.RenderTree
+#endif
 {
     /// <summary>
     /// Types in the Microsoft.AspNetCore.Components.RenderTree are not recommended for use outside

+ 4 - 0
src/Components/Components/src/RenderTree/RenderTreeFrameType.cs

@@ -1,7 +1,11 @@
 // Copyright (c) .NET Foundation. All rights reserved.
 // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
 
+#if IGNITOR
+namespace Ignitor
+#else
 namespace Microsoft.AspNetCore.Components.RenderTree
+#endif
 {
     /// <summary>
     /// Types in the Microsoft.AspNetCore.Components.RenderTree are not recommended for use outside

+ 9 - 10
src/Components/ComponentsNoDeps.slnf

@@ -21,23 +21,22 @@
       "Blazor\\testassets\\MonoSanityClient\\MonoSanityClient.csproj",
       "Blazor\\testassets\\MonoSanity\\MonoSanity.csproj",
       "Blazor\\testassets\\StandaloneApp\\StandaloneApp.csproj",
-      "Forms\\src\\Microsoft.AspNetCore.Components.Forms.csproj",
-      "Forms\\test\\Microsoft.AspNetCore.Components.Forms.Tests.csproj",
-      "Web\\src\\Microsoft.AspNetCore.Components.Web.csproj",
-      "Web\\test\\Microsoft.AspNetCore.Components.Web.Tests.csproj",
       "Components\\perf\\Microsoft.AspNetCore.Components.Performance.csproj",
       "Components\\src\\Microsoft.AspNetCore.Components.csproj",
       "Components\\test\\Microsoft.AspNetCore.Components.Tests.csproj",
+      "Forms\\src\\Microsoft.AspNetCore.Components.Forms.csproj",
+      "Forms\\test\\Microsoft.AspNetCore.Components.Forms.Tests.csproj",
+      "Samples\\BlazorServer.Sample\\BlazorServer.Sample.csproj",
       "Server\\src\\Microsoft.AspNetCore.Components.Server.csproj",
       "Server\\test\\Microsoft.AspNetCore.Components.Server.Tests.csproj",
+      "Web\\src\\Microsoft.AspNetCore.Components.Web.csproj",
+      "Web\\test\\Microsoft.AspNetCore.Components.Web.Tests.csproj",
       "test\\E2ETest\\Microsoft.AspNetCore.Components.E2ETests.csproj",
+      "test\\Ignitor.Test\\Ignitor.Test.csproj",
       "test\\testassets\\BasicTestApp\\BasicTestApp.csproj",
-      "test\\testassets\\ComponentsApp.App\\ComponentsApp.App.csproj",
-      "test\\testassets\\ComponentsApp.Server\\ComponentsApp.Server.csproj",
-      "test\\testassets\\TestContentPackage\\TestContentPackage.csproj",
-      "test\\testassets\\TestServer\\Components.TestServer.csproj",
       "test\\testassets\\Ignitor\\Ignitor.csproj",
-      "test\\Ignitor.Test\\Ignitor.Test.csproj"
+      "test\\testassets\\TestContentPackage\\TestContentPackage.csproj",
+      "test\\testassets\\TestServer\\Components.TestServer.csproj"
     ]
   }
-}
+}

+ 26 - 5
src/Components/test/testassets/Ignitor/BlazorClient.cs → src/Components/Ignitor/src/BlazorClient.cs

@@ -16,7 +16,7 @@ using Microsoft.Extensions.Logging;
 
 namespace Ignitor
 {
-    public class BlazorClient
+    public class BlazorClient : IAsyncDisposable
     {
         private const string MarkerPattern = ".*?<!--Blazor:(.*?)-->.*?";
 
@@ -54,6 +54,8 @@ namespace Ignitor
 
         private TaskCompletionSource<object> TaskCompletionSource { get; }
 
+        private CancellableOperation<CapturedAttachComponentCall> NextAttachComponentReceived { get; set; }
+
         private CancellableOperation<CapturedRenderBatch> NextBatchReceived { get; set; }
 
         private CancellableOperation<string> NextErrorReceived { get; set; }
@@ -82,7 +84,7 @@ namespace Ignitor
 
         public bool ImplicitWait => DefaultOperationTimeout != null;
 
-        public HubConnection HubConnection { get; set; }
+        public HubConnection HubConnection { get; private set; }
 
         public Task<CapturedRenderBatch> PrepareForNextBatch(TimeSpan? timeout)
         {
@@ -345,6 +347,7 @@ namespace Ignitor
             HubConnection = builder.Build();
             await HubConnection.StartAsync(CancellationToken);
 
+            HubConnection.On<int, string>("JS.AttachComponent", OnAttachComponent);
             HubConnection.On<int, string, string>("JS.BeginInvokeJS", OnBeginInvokeJS);
             HubConnection.On<string>("JS.EndInvokeDotNet", OnEndInvokeDotNet);
             HubConnection.On<int, byte[]>("JS.RenderBatch", OnRenderBatch);
@@ -376,6 +379,14 @@ namespace Ignitor
             NextDotNetInteropCompletionReceived?.Completion?.TrySetResult(null);
         }
 
+        private void OnAttachComponent(int componentId, string domSelector)
+        {
+            var call = new CapturedAttachComponentCall(componentId, domSelector);
+            Operations?.AttachComponent.Enqueue(call);
+
+            NextAttachComponentReceived?.Completion?.TrySetResult(call);
+        }
+
         private void OnBeginInvokeJS(int asyncHandle, string identifier, string argsJson)
         {
             var call = new CapturedJSInteropCall(asyncHandle, identifier, argsJson);
@@ -421,6 +432,7 @@ namespace Ignitor
             NextBatchReceived?.Completion?.TrySetException(exception);
             NextDotNetInteropCompletionReceived?.Completion.TrySetException(exception);
             NextJSInteropReceived?.Completion.TrySetException(exception);
+            NextAttachComponentReceived?.Completion?.TrySetException(exception);
             NextErrorReceived?.Completion?.TrySetResult(null);
         }
 
@@ -481,7 +493,7 @@ namespace Ignitor
         {
             if (!Hive.TryFindElementById(id, out var element))
             {
-                throw new InvalidOperationException("Element not found.");
+                throw new InvalidOperationException($"Element with id '{id}' was not found.");
             }
 
             return element;
@@ -544,8 +556,9 @@ namespace Ignitor
             var markers = matches.Select(s => (value: s.Groups[1].Value, parsed: JsonDocument.Parse(s.Groups[1].Value)))
                 .Where(s =>
                 {
-                    var markerType = s.parsed.RootElement.GetProperty("type");
-                    return markerType.ValueKind != JsonValueKind.Undefined && markerType.GetString() == "server";
+                    return s.parsed.RootElement.TryGetProperty("type", out var markerType) &&
+                        markerType.ValueKind != JsonValueKind.Undefined &&
+                        markerType.GetString() == "server";
                 })
                 .OrderBy(p => p.parsed.RootElement.GetProperty("sequence").GetInt32())
                 .Select(p => p.value)
@@ -553,5 +566,13 @@ namespace Ignitor
 
             return markers;
         }
+
+        public async ValueTask DisposeAsync()
+        {
+            if (HubConnection != null)
+            {
+                await HubConnection.DisposeAsync();
+            }
+        }
     }
 }

+ 17 - 0
src/Components/Ignitor/src/CapturedAttachComponentCall.cs

@@ -0,0 +1,17 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+namespace Ignitor
+{
+    public readonly struct CapturedAttachComponentCall
+    {
+        public CapturedAttachComponentCall(int componentId, string selector)
+        {
+            ComponentId = componentId;
+            Selector = selector;
+        }
+
+        public int ComponentId { get; }
+        public string Selector { get; }
+    }
+}

+ 0 - 0
src/Components/test/testassets/Ignitor/CapturedJSInteropCall.cs → src/Components/Ignitor/src/CapturedJSInteropCall.cs


+ 0 - 0
src/Components/test/testassets/Ignitor/CapturedRenderBatch.cs → src/Components/Ignitor/src/CapturedRenderBatch.cs


+ 0 - 0
src/Components/test/testassets/Ignitor/CommentNode.cs → src/Components/Ignitor/src/CommentNode.cs


+ 0 - 0
src/Components/test/testassets/Ignitor/ComponentNode.cs → src/Components/Ignitor/src/ComponentNode.cs


+ 16 - 0
src/Components/Ignitor/src/ComponentState.cs

@@ -0,0 +1,16 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+namespace Ignitor
+{
+    public class ComponentState
+    {
+        public ComponentState(int componentId)
+        {
+            ComponentId = componentId;
+        }
+
+        public int ComponentId { get; }
+        public IComponent Component { get; }
+    }
+}

+ 1 - 1
src/Components/test/testassets/Ignitor/ContainerNode.cs → src/Components/Ignitor/src/ContainerNode.cs

@@ -41,7 +41,7 @@ namespace Ignitor
             if (childIndex < Children.Count)
             {
                 // Insert
-                _children[childIndex] = child;
+                _children.Insert(childIndex, child);
             }
             else
             {

+ 0 - 2
src/Components/test/testassets/Ignitor/ElementHive.cs → src/Components/Ignitor/src/ElementHive.cs

@@ -3,8 +3,6 @@
 
 using System;
 using System.Collections.Generic;
-using Microsoft.AspNetCore.Components.Rendering;
-using Microsoft.AspNetCore.Components.RenderTree;
 
 namespace Ignitor
 {

+ 5 - 9
src/Components/test/testassets/Ignitor/ElementNode.cs → src/Components/Ignitor/src/ElementNode.cs

@@ -5,10 +5,6 @@ using System;
 using System.Collections.Generic;
 using System.Text.Json;
 using System.Threading.Tasks;
-using Microsoft.AspNetCore.Components;
-using Microsoft.AspNetCore.Components.Rendering;
-using Microsoft.AspNetCore.Components.RenderTree;
-using Microsoft.AspNetCore.Components.Web;
 using Microsoft.AspNetCore.SignalR.Client;
 
 namespace Ignitor
@@ -71,17 +67,17 @@ namespace Ignitor
                 throw new InvalidOperationException("Element does not have a change event.");
             }
 
-            var args = new ChangeEventArgs()
+            var args = new
             {
                 Value = value
             };
 
-            var webEventDescriptor = new WebEventDescriptor()
+            var webEventDescriptor = new
             {
                 BrowserRendererId = 0,
                 EventHandlerId = changeEventDescriptor.EventId,
                 EventArgsType = "change",
-                EventFieldInfo = new EventFieldInfo
+                EventFieldInfo = new
                 {
                     ComponentId = 0,
                     FieldValue = value
@@ -98,12 +94,12 @@ namespace Ignitor
                 throw new InvalidOperationException("Element does not have a click event.");
             }
 
-            var mouseEventArgs = new MouseEventArgs()
+            var mouseEventArgs = new
             {
                 Type = clickEventDescriptor.EventName,
                 Detail = 1
             };
-            var webEventDescriptor = new WebEventDescriptor
+            var webEventDescriptor = new
             {
                 BrowserRendererId = 0,
                 EventHandlerId = clickEventDescriptor.EventId,

+ 29 - 0
src/Components/Ignitor/src/ElementReference.cs

@@ -0,0 +1,29 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Ignitor
+{
+    /// <summary>
+    /// Represents a reference to a rendered element.
+    /// </summary>
+    public readonly struct ElementReference
+    {
+        /// <summary>
+        /// Gets a unique identifier for <see cref="ElementReference" />.
+        /// </summary>
+        /// <remarks>
+        /// The Id is unique at least within the scope of a given user/circuit.
+        /// This property is public to support Json serialization and should not be used by user code.
+        /// </remarks>
+        public string Id { get; }
+
+        public ElementReference(string id)
+        {
+            Id = id;
+        }
+    }
+}

+ 0 - 0
src/Components/test/testassets/Ignitor/Error.cs → src/Components/Ignitor/src/Error.cs


+ 10 - 0
src/Components/Ignitor/src/IComponent.cs

@@ -0,0 +1,10 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Ignitor
+{
+    public interface IComponent
+    {
+    }
+}

Alguns ficheiros não foram mostrados porque muitos ficheiros mudaram neste diff