Browse Source

Use stages pipeline (#13040)

- #11924
- change ci.yml to use stages and post-build.yml
  - add use of publish-build-assets.yml and post-build.yml
  - create manifests and push to artifacts in last build step of each job
    - pass more MSBuild properties into those builds
    - use Arcade to publish installers
  - use distinct `$(AssetManifestFileName)` values per job
    - set global property to override what's hard-coded in Publish.proj
- change codesign-xplat.yml to use empty.proj and normal Arcade signing and publication process
  - remove XPlatPackageSigner.proj
- change default-build.yml to use job.yml
  - remove unused parameters e.g. `matrix`, `poolName`, `variables`
  - use `enableMicrobuild` and `enablePublishTestResults` to eliminate duplicate build steps
- add .dll's and .exe's as files to sign w/ Microsoft400
  - add signcheck exclusions
- remove custom manifest generation i.e. the `GenerateBuildAssetManifest` target and related artifacts
- update docker infrastructure to use same paths in and out of the container
  - avoids problems adding to artifacts from within the builds
- correct typo in build.sh
- use `$env:DOTNET_INSTALL_DIR` in `DotNetCommands`
  - relax expectations that an arch-specific folder exists under (say) `$env:DOTNET_HOME`
  - avoids need to define `$env:DOTNET_HOME` in all jobs on CI
- update dependencies from dotnet/arcade build '20190908.2'
  - upgrade to eg. Arcade SDK '1.0.0-beta.19458.2' package version
  - pick up dotnet/arcade@dd593acc8b08 fix
    - enable use of `%(PublishFlatContainer)` metadata and correct signing validation issues
- use `$(DotNetFinalVersionKind)` in preparation for servicing builds
  - set `$(IsStableBuild)` for use in Arcade infrastructure
- disable signing validation for now (see #13864)

nits:
- upload logs in first artifact
- remove attempts to package non-existent VSIX
  - follow-up to 29cf7ecb80b1
- respect verbosity setting in build.sh
- add more information to Artifacts.md
- enable test signing in internal PRs
Doug Bunting 6 years ago
parent
commit
04705ee4f1

+ 547 - 491
.azure/pipelines/ci.yml

@@ -22,517 +22,573 @@ variables:
   value: true
   value: true
 - name: _TeamName
 - name: _TeamName
   value:  AspNetCore
   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
   - name: _BuildArgs
     value: ''
     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
 
 
-    # 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)
-      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)
+        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
+      artifacts:
+      - name: Windows_Logs
+        path: artifacts/log/
+        publishOnError: true
+      - name: Windows_Packages
+        path: artifacts/packages/
 
 
-# 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
+  # 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
+      - name: Windows_arm_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 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
+      - name: MacOS_x64_Packages
+        path: artifacts/packages/
+  - template: jobs/codesign-xplat.yml
+    parameters:
+      inputName: MacOS_x64
 
 
-# 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 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
+      - name: Linux_x64_Packages
+        path: artifacts/packages/
+  - template: jobs/codesign-xplat.yml
+    parameters:
+      inputName: Linux_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 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
+      - name: Linux_arm_Packages
+        path: artifacts/packages/
+  - template: jobs/codesign-xplat.yml
+    parameters:
+      inputName: Linux_arm
 
 
-# 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 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
+      - 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: 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 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
+      - 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: 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 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
+      - 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
+      artifacts:
+      - name: Windows_Test_Logs
+        path: artifacts/log/
+        publishOnError: true
+      - name: Windows_Test_Results
+        path: artifacts/TestResults/
+        publishOnError: 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
+      - name: Windows_Test_Templates_Results
+        path: artifacts/TestResults/
+        publishOnError: 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
+  - 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
+
+  - 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
+
+  # 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
+    - task: UseDotNet@2
+      displayName: 'Use .NET Core sdk'
+      inputs:
+        packageType: sdk
+        # The SDK version selected here is intentionally supposed to use the latest release
+        # For the purpose of building Linux distros, we can't depend on features of the SDK
+        # which may not exist in pre-built versions of the SDK
+        # Pinning to preview 8 since preview 9 has breaking changes
+        version: 3.0.100-preview8-013656
+        installationPath: $(DotNetCoreSdkDir)
+        includePreviewVersions: true
+    - 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
       continueOnError: true
-    artifacts:
-    - name: Linux_Test_Logs
-      path: artifacts/log/
-      publishOnError: true
-    - name: Linux_Test_Results
-      path: artifacts/TestResults/
-      publishOnError: 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
-  - task: UseDotNet@2
-    displayName: 'Use .NET Core sdk'
-    inputs:
-      packageType: sdk
-      # The SDK version selected here is intentionally supposed to use the latest release
-      # For the purpose of building Linux distros, we can't depend on features of the SDK
-      # which may not exist in pre-built versions of the SDK
-      # Pinning to preview 8 since preview 9 has breaking changes
-      # version: 3.0.x
-      version: 3.0.100-preview8-013656
-      installationPath: $(DotNetCoreSdkDir)
-      includePreviewVersions: true
-  - 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

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

@@ -19,13 +19,30 @@ jobs:
       displayName: Download ${{ parameters.inputName }} artifacts
       displayName: Download ${{ parameters.inputName }} artifacts
       inputs:
       inputs:
         artifactName: ${{ parameters.inputName }}_Packages
         artifactName: ${{ parameters.inputName }}_Packages
-        downloadPath: $(Build.StagingDirectory)/deps/
+        downloadPath: $(Build.StagingDirectory)/downloaded_packages/
         itemPattern: '**/*.nupkg'
         itemPattern: '**/*.nupkg'
-    - task: MSBuild@1
-      displayName: Code-sign .nupkg files
+    - task: CopyFiles@2
+      displayName: Copy packages to ArtifactsShippingPackagesDir
       inputs:
       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:
     artifacts:
+    - name: CodeSign_Xplat_${{ parameters.inputName }}_Logs
+      path: artifacts/log/
+      publishOnError: true
     - name: ${{ parameters.inputName }}_Packages_Signed
     - name: ${{ parameters.inputName }}_Packages_Signed
-      path: $(Build.StagingDirectory)\deps\${{ parameters.inputName }}_Packages\
+      path: artifacts/packages/

+ 158 - 191
.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
 #       The name of the job. Defaults to the name of the OS. No spaces allowed
 #   jobDisplayName: string
 #   jobDisplayName: string
 #       The friendly job name to display in the UI. Defaults to the name of the OS.
 #       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
 #   agentOs: string
 #       Used in templates to define variables which are OS specific. Typically from the set { Windows, Linux, macOS }
 #       Used in templates to define variables which are OS specific. Typically from the set { Windows, Linux, macOS }
 #   buildArgs: string
 #   buildArgs: string
@@ -21,20 +17,18 @@
 #   afterBuild: [steps]
 #   afterBuild: [steps]
 #       Additional steps to run after build.sh/cmd
 #       Additional steps to run after build.sh/cmd
 #   artifacts: [array]
 #   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
 #           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 ]
 #   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
 #   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
 #   codeSign: boolean
 #       This build definition is enabled for code signing. (Only applies to Windows)
 #       This build definition is enabled for code signing. (Only applies to Windows)
 #   buildDirectory: string
 #   buildDirectory: string
@@ -48,20 +42,16 @@
 
 
 parameters:
 parameters:
   agentOs: 'Windows'
   agentOs: 'Windows'
-  poolName: ''
-  poolVmImage: ''
   buildArgs: ''
   buildArgs: ''
   configuration: 'Release'
   configuration: 'Release'
   beforeBuild: []
   beforeBuild: []
   # steps: []  don't define an empty object default because there is no way in template expression yet to check "if isEmpty(parameters.steps)"
   # steps: []  don't define an empty object default because there is no way in template expression yet to check "if isEmpty(parameters.steps)"
   afterBuild: []
   afterBuild: []
   codeSign: false
   codeSign: false
-  variables: {}
   dependsOn: ''
   dependsOn: ''
   condition: ''
   condition: ''
   # jobName: '' - use agentOs by default.
   # jobName: '' - use agentOs by default.
   # jobDisplayName: '' - 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:  []
   artifacts:  []
   buildDirectory: ''
   buildDirectory: ''
   buildScript: ''
   buildScript: ''
@@ -75,182 +65,159 @@ parameters:
   cancelTimeoutInMinutes: 15
   cancelTimeoutInMinutes: 15
 
 
 jobs:
 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
           # 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 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 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()
 
 
-  - ${{ 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
+    - ${{ 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.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)
-
-
-  - ${{ 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>
     <IsSampleProject Condition="$(RepoRelativeProjectDir.Contains('sample'))">true</IsSampleProject>
     <IsAnalyzersProject Condition="$(MSBuildProjectName.EndsWith('.Analyzers'))">true</IsAnalyzersProject>
     <IsAnalyzersProject Condition="$(MSBuildProjectName.EndsWith('.Analyzers'))">true</IsAnalyzersProject>
     <IsShipping Condition="'$(IsSampleProject)' == 'true' or '$(IsTestAssetProject)' == 'true' or '$(IsBenchmarkProject)' == 'true' or '$(IsUnitTestProject)' == 'true'">false</IsShipping>
     <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>
   </PropertyGroup>
 
 
   <Import Project="eng\FlakyTests.BeforeArcade.props" />
   <Import Project="eng\FlakyTests.BeforeArcade.props" />
@@ -119,7 +128,7 @@
     <BuildProjectReferences Condition=" '$(NoBuild)' == 'true' ">false</BuildProjectReferences>
     <BuildProjectReferences Condition=" '$(NoBuild)' == 'true' ">false</BuildProjectReferences>
   </PropertyGroup>
   </PropertyGroup>
 
 
-  <!-- Artifacts layout -->
+  <!-- Artifacts layout. Keep these values consistent with items defined in eng/Publishing.props. -->
   <PropertyGroup>
   <PropertyGroup>
     <InstallersOutputPath>$(ArtifactsDir)installers\$(Configuration)\</InstallersOutputPath>
     <InstallersOutputPath>$(ArtifactsDir)installers\$(Configuration)\</InstallersOutputPath>
     <SymbolsOutputPath>$(ArtifactsDir)symbols\$(Configuration)\</SymbolsOutputPath>
     <SymbolsOutputPath>$(ArtifactsDir)symbols\$(Configuration)\</SymbolsOutputPath>

+ 2 - 1
Directory.Build.targets

@@ -30,7 +30,8 @@
 
 
   <PropertyGroup Label="Versioning settings">
   <PropertyGroup Label="Versioning settings">
     <!-- The 'human friendly' version to display in installers. In pre-release builds, this might be "2.0.7 Preview 2 Build 12356". In final builds, it should be "2.0.7" -->
     <!-- The 'human friendly' version to display in installers. In pre-release builds, this might be "2.0.7 Preview 2 Build 12356". In final builds, it should be "2.0.7" -->
-    <BrandingVersionSuffix>$(PreReleaseBrandingLabel) Build $(VersionSuffix)</BrandingVersionSuffix>
+    <BrandingVersionSuffix />
+    <BrandingVersionSuffix Condition="$(IncludePreReleaseLabelInPackageVersion)">$(PreReleaseBrandingLabel) Build $(VersionSuffix)</BrandingVersionSuffix>
     <PackageBrandingVersion>$(VersionPrefix)</PackageBrandingVersion>
     <PackageBrandingVersion>$(VersionPrefix)</PackageBrandingVersion>
     <PackageBrandingVersion Condition=" '$(VersionSuffix)' != '' ">$(PackageBrandingVersion) $(BrandingVersionSuffix.Trim())</PackageBrandingVersion>
     <PackageBrandingVersion Condition=" '$(VersionSuffix)' != '' ">$(PackageBrandingVersion) $(BrandingVersionSuffix.Trim())</PackageBrandingVersion>
 
 

+ 5 - 1
build.sh

@@ -221,7 +221,7 @@ if [ "$build_deps" = false ]; then
     msbuild_args[${#msbuild_args[*]}]="-p:BuildProjectReferences=false"
     msbuild_args[${#msbuild_args[*]}]="-p:BuildProjectReferences=false"
 fi
 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 [ -z "$build_nodejs" ]; then
         if [ -x "$(command -v node)" ]; 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."
             __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
 fi
 msbuild_args[${#msbuild_args[*]}]="-p:Configuration=$configuration"
 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
 # Initialize global variables need to be set before the import of Arcade is imported
 restore=$run_restore
 restore=$run_restore
 
 

+ 2 - 1
dockerbuild.sh

@@ -124,6 +124,7 @@ docker build "$(dirname "$dockerfile")" \
     --build-arg "USER=$(whoami)" \
     --build-arg "USER=$(whoami)" \
     --build-arg "USER_ID=$(id -u)" \
     --build-arg "USER_ID=$(id -u)" \
     --build-arg "GROUP_ID=$(id -g)" \
     --build-arg "GROUP_ID=$(id -g)" \
+    --build-arg "WORKDIR=$DIR" \
     --tag $tagname \
     --tag $tagname \
     -f "$dockerfile"
     -f "$dockerfile"
 
 
@@ -138,7 +139,7 @@ docker run \
     -e BUILD_SOURCEBRANCH \
     -e BUILD_SOURCEBRANCH \
     -e DOTNET_CLI_TELEMETRY_OPTOUT \
     -e DOTNET_CLI_TELEMETRY_OPTOUT \
     -e Configuration \
     -e Configuration \
-    -v "$DIR:/code/build" \
+    -v "$DIR:$DIR" \
     ${docker_args[@]+"${docker_args[@]}"} \
     ${docker_args[@]+"${docker_args[@]}"} \
     $tagname \
     $tagname \
     ./build.sh \
     ./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.
 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/
 artifacts/
   installers/
   installers/
     $(Configuration)/
     $(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/
   packages/
     $(Configuration)/
     $(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/
   VSSetup/
     $(Configuration)/
     $(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)" />
       SharedFrameworkTargetFramework="netcoreapp$(AspNetCoreMajorVersion).$(AspNetCoreMinorVersion)" />
   </Target>
   </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>
 </Project>

+ 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>false</IsShipping>
+        <ManifestArtifactData>NonShipping=true;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=".jar" CertificateName="MicrosoftJARSHA2" />
     <FileExtensionSignInfo Include=".ps1;.psd1;.psm1;.psc1" CertificateName="Microsoft400" />
     <FileExtensionSignInfo Include=".ps1;.psd1;.psm1;.psc1" CertificateName="Microsoft400" />
+    <FileExtensionSignInfo Include=".dll;.exe" CertificateName="Microsoft400" />
     <FileExtensionSignInfo Include=".nupkg" CertificateName="NuGet" />
     <FileExtensionSignInfo Include=".nupkg" CertificateName="NuGet" />
     <FileExtensionSignInfo Include=".vsix" CertificateName="VsixSHA2" />
     <FileExtensionSignInfo Include=".vsix" CertificateName="VsixSHA2" />
     <FileExtensionSignInfo Include=".zip" CertificateName="None" />
     <FileExtensionSignInfo Include=".zip" CertificateName="None" />

+ 3 - 3
eng/Version.Details.xml

@@ -412,15 +412,15 @@
       <Uri>https://github.com/aspnet/Extensions</Uri>
       <Uri>https://github.com/aspnet/Extensions</Uri>
       <Sha>73c259904d5db01bbeede15df2a72d1b94cb3306</Sha>
       <Sha>73c259904d5db01bbeede15df2a72d1b94cb3306</Sha>
     </Dependency>
     </Dependency>
-    <Dependency Name="Microsoft.DotNet.GenAPI" Version="1.0.0-beta.19456.10">
+    <Dependency Name="Microsoft.DotNet.GenAPI" Version="1.0.0-beta.19458.2">
       <Uri>https://github.com/dotnet/arcade</Uri>
       <Uri>https://github.com/dotnet/arcade</Uri>
       <Sha>2d393243ba4a0c95c2c18aa266df6e0f43ffe22d</Sha>
       <Sha>2d393243ba4a0c95c2c18aa266df6e0f43ffe22d</Sha>
     </Dependency>
     </Dependency>
-    <Dependency Name="Microsoft.DotNet.Arcade.Sdk" Version="1.0.0-beta.19456.10">
+    <Dependency Name="Microsoft.DotNet.Arcade.Sdk" Version="1.0.0-beta.19458.2">
       <Uri>https://github.com/dotnet/arcade</Uri>
       <Uri>https://github.com/dotnet/arcade</Uri>
       <Sha>2d393243ba4a0c95c2c18aa266df6e0f43ffe22d</Sha>
       <Sha>2d393243ba4a0c95c2c18aa266df6e0f43ffe22d</Sha>
     </Dependency>
     </Dependency>
-    <Dependency Name="Microsoft.DotNet.Helix.Sdk" Version="2.0.0-beta.19456.10">
+    <Dependency Name="Microsoft.DotNet.Helix.Sdk" Version="2.0.0-beta.19458.2">
       <Uri>https://github.com/dotnet/arcade</Uri>
       <Uri>https://github.com/dotnet/arcade</Uri>
       <Sha>2d393243ba4a0c95c2c18aa266df6e0f43ffe22d</Sha>
       <Sha>2d393243ba4a0c95c2c18aa266df6e0f43ffe22d</Sha>
     </Dependency>
     </Dependency>

+ 5 - 3
eng/Versions.props

@@ -10,8 +10,10 @@
     <AspNetCoreMinorVersion>0</AspNetCoreMinorVersion>
     <AspNetCoreMinorVersion>0</AspNetCoreMinorVersion>
     <AspNetCorePatchVersion>0</AspNetCorePatchVersion>
     <AspNetCorePatchVersion>0</AspNetCorePatchVersion>
     <PreReleasePreviewNumber>2</PreReleasePreviewNumber>
     <PreReleasePreviewNumber>2</PreReleasePreviewNumber>
-    <PreReleaseVersionLabel>rc$(PreReleasePreviewNumber)</PreReleaseVersionLabel>
-    <PreReleaseBrandingLabel>Release Candidate $(PreReleasePreviewNumber)</PreReleaseBrandingLabel>
+    <IncludePreReleaseLabelInPackageVersion>true</IncludePreReleaseLabelInPackageVersion>
+    <IncludePreReleaseLabelInPackageVersion Condition=" '$(IsStableBuild)' == 'true' ">false</IncludePreReleaseLabelInPackageVersion>
+    <PreReleaseVersionLabel Condition="$(IncludePreReleaseLabelInPackageVersion)">rc$(PreReleasePreviewNumber)</PreReleaseVersionLabel>
+    <PreReleaseBrandingLabel Condition="$(IncludePreReleaseLabelInPackageVersion)">Release Candidate $(PreReleasePreviewNumber)</PreReleaseBrandingLabel>
     <!-- Blazor Client packages will not RTM with 3.0 -->
     <!-- Blazor Client packages will not RTM with 3.0 -->
     <BlazorClientPreReleasePreviewNumber>9</BlazorClientPreReleasePreviewNumber>
     <BlazorClientPreReleasePreviewNumber>9</BlazorClientPreReleasePreviewNumber>
     <BlazorClientPreReleaseVersionLabel>preview$(BlazorClientPreReleasePreviewNumber)</BlazorClientPreReleaseVersionLabel>
     <BlazorClientPreReleaseVersionLabel>preview$(BlazorClientPreReleasePreviewNumber)</BlazorClientPreReleaseVersionLabel>
@@ -53,7 +55,7 @@
   -->
   -->
   <PropertyGroup Label="Automated">
   <PropertyGroup Label="Automated">
     <!-- Packages from dotnet/arcade -->
     <!-- Packages from dotnet/arcade -->
-    <MicrosoftDotNetGenAPIPackageVersion>1.0.0-beta.19456.10</MicrosoftDotNetGenAPIPackageVersion>
+    <MicrosoftDotNetGenAPIPackageVersion>1.0.0-beta.19458.2</MicrosoftDotNetGenAPIPackageVersion>
     <!-- Packages from dotnet/roslyn -->
     <!-- Packages from dotnet/roslyn -->
     <MicrosoftNetCompilersToolsetPackageVersion>3.3.1-beta3-19454-05</MicrosoftNetCompilersToolsetPackageVersion>
     <MicrosoftNetCompilersToolsetPackageVersion>3.3.1-beta3-19454-05</MicrosoftNetCompilersToolsetPackageVersion>
     <!-- Packages from dotnet/core-setup -->
     <!-- Packages from dotnet/core-setup -->

+ 2 - 1
eng/docker/alpine.Dockerfile

@@ -2,8 +2,9 @@ FROM microsoft/dotnet:2.1.0-preview1-runtime-deps-alpine
 ARG USER
 ARG USER
 ARG USER_ID
 ARG USER_ID
 ARG GROUP_ID
 ARG GROUP_ID
+ARG WORKDIR
 
 
-WORKDIR /code/build
+WORKDIR ${WORKDIR}
 RUN mkdir -p "/home/$USER" && chown "${USER_ID}:${GROUP_ID}" "/home/$USER"
 RUN mkdir -p "/home/$USER" && chown "${USER_ID}:${GROUP_ID}" "/home/$USER"
 ENV HOME "/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
 ARG USER_ID
 ARG USER_ID
 ARG GROUP_ID
 ARG GROUP_ID
+ARG WORKDIR
 
 
-WORKDIR /code/build
+WORKDIR ${WORKDIR}
 RUN mkdir -p "/home/$USER" && chown "${USER_ID}:${GROUP_ID}" "/home/$USER"
 RUN mkdir -p "/home/$USER" && chown "${USER_ID}:${GROUP_ID}" "/home/$USER"
 ENV HOME "/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
 ARG USER_ID
 ARG USER_ID
 ARG GROUP_ID
 ARG GROUP_ID
+ARG WORKDIR
 
 
-WORKDIR /code/build
+WORKDIR ${WORKDIR}
 
 
 RUN useradd -m ${USER} --uid ${USER_ID} -g root
 RUN useradd -m ${USER} --uid ${USER_ID} -g root
 RUN echo '${USER} ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers
 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
 ARG USER_ID
 ARG USER_ID
 ARG GROUP_ID
 ARG GROUP_ID
+ARG WORKDIR
 
 
-WORKDIR /code/build
+WORKDIR ${WORKDIR}
 RUN mkdir -p "/home/$USER" && chown "${USER_ID}:${GROUP_ID}" "/home/$USER"
 RUN mkdir -p "/home/$USER" && chown "${USER_ID}:${GROUP_ID}" "/home/$USER"
 ENV HOME "/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>

+ 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>netcoreapp3.0</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": {
   "msbuild-sdks": {
     "Yarn.MSBuild": "1.15.2",
     "Yarn.MSBuild": "1.15.2",
-    "Microsoft.DotNet.Arcade.Sdk": "1.0.0-beta.19456.10",
-    "Microsoft.DotNet.Helix.Sdk": "2.0.0-beta.19456.10"
+    "Microsoft.DotNet.Arcade.Sdk": "1.0.0-beta.19458.2",
+    "Microsoft.DotNet.Helix.Sdk": "2.0.0-beta.19458.2"
   }
   }
 }
 }

+ 1 - 1
src/Components/Blazor/Directory.Build.props

@@ -4,6 +4,6 @@
   <PropertyGroup>
   <PropertyGroup>
     <!-- Override prerelease label and use preview 9, even in the final build -->
     <!-- Override prerelease label and use preview 9, even in the final build -->
     <PreReleaseVersionLabel>$(BlazorClientPreReleaseVersionLabel)</PreReleaseVersionLabel>
     <PreReleaseVersionLabel>$(BlazorClientPreReleaseVersionLabel)</PreReleaseVersionLabel>
-    <DotNetFinalVersionKind></DotNetFinalVersionKind>
+    <DotNetFinalVersionKind />
   </PropertyGroup>
   </PropertyGroup>
 </Project>
 </Project>

+ 21 - 4
src/Hosting/Server.IntegrationTesting/src/Common/DotNetCommands.cs

@@ -16,8 +16,13 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting
         // Compare to https://github.com/aspnet/BuildTools/blob/314c98e4533217a841ff9767bb38e144eb6c93e4/tools/KoreBuild.Console/Commands/CommandContext.cs#L76
         // Compare to https://github.com/aspnet/BuildTools/blob/314c98e4533217a841ff9767bb38e144eb6c93e4/tools/KoreBuild.Console/Commands/CommandContext.cs#L76
         public static string GetDotNetHome()
         public static string GetDotNetHome()
         {
         {
+            // runtest.* scripts throughout the repo define $env:DOTNET_HOME
             var dotnetHome = Environment.GetEnvironmentVariable("DOTNET_HOME");
             var dotnetHome = Environment.GetEnvironmentVariable("DOTNET_HOME");
+            // /activate.* and runtest.* scripts define $env:DOTNET_ROOT and (for /activate.*) $env:{DOTNET_ROOT(x86)}
             var dotnetRoot = Environment.GetEnvironmentVariable("DOTNET_ROOT");
             var dotnetRoot = Environment.GetEnvironmentVariable("DOTNET_ROOT");
+            // /eng/common/tools.* scripts define $env:DOTNET_INSTALL_DIR
+            var dotnetInstallDir = Environment.GetEnvironmentVariable("DOTNET_INSTALL_DIR");
+
             var userProfile = Environment.GetEnvironmentVariable("USERPROFILE");
             var userProfile = Environment.GetEnvironmentVariable("USERPROFILE");
             var home = Environment.GetEnvironmentVariable("HOME");
             var home = Environment.GetEnvironmentVariable("HOME");
 
 
@@ -28,8 +33,19 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting
             }
             }
             else if (!string.IsNullOrEmpty(dotnetRoot))
             else if (!string.IsNullOrEmpty(dotnetRoot))
             {
             {
-                // DOTNET_ROOT has x64 appended to the path, which we append again in GetDotNetInstallDir
-                result = dotnetRoot.Substring(0, dotnetRoot.Length - 3);
+                if (dotnetRoot.EndsWith("x64"))
+                {
+                    // DOTNET_ROOT has x64 appended to the path, which we append again in GetDotNetInstallDir
+                    result = dotnetRoot[0..^3];
+                }
+                else
+                {
+                    result = dotnetRoot;
+                }
+            }
+            else if (!string.IsNullOrEmpty(dotnetInstallDir))
+            {
+                result = dotnetInstallDir;
             }
             }
             else if (!string.IsNullOrEmpty(userProfile))
             else if (!string.IsNullOrEmpty(userProfile))
             {
             {
@@ -46,9 +62,10 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting
         public static string GetDotNetInstallDir(RuntimeArchitecture arch)
         public static string GetDotNetInstallDir(RuntimeArchitecture arch)
         {
         {
             var dotnetDir = DotNetHome;
             var dotnetDir = DotNetHome;
-            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
+            var archSpecificDir = Path.Combine(dotnetDir, arch.ToString());
+            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && Directory.Exists(archSpecificDir))
             {
             {
-                dotnetDir = Path.Combine(dotnetDir, arch.ToString());
+                dotnetDir = archSpecificDir;
             }
             }
 
 
             return dotnetDir;
             return dotnetDir;