diff --git a/eng/SourceBuild.props b/eng/SourceBuild.props
new file mode 100644
index 00000000000..fb81956bb63
--- /dev/null
+++ b/eng/SourceBuild.props
@@ -0,0 +1,10 @@
+
+
+
+ nuget-client
+ true
+
+ 1.0.0
+
+
+
diff --git a/eng/SourceBuildPrebuiltBaseline.xml b/eng/SourceBuildPrebuiltBaseline.xml
new file mode 100644
index 00000000000..c1b6dfbf053
--- /dev/null
+++ b/eng/SourceBuildPrebuiltBaseline.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/eng/pipelines/templates/Source_Build.yml b/eng/pipelines/templates/Source_Build.yml
new file mode 100644
index 00000000000..38bf8c1bcbe
--- /dev/null
+++ b/eng/pipelines/templates/Source_Build.yml
@@ -0,0 +1,27 @@
+steps:
+- task: PowerShell@2
+ displayName: "Update Build Number"
+ inputs:
+ targetType: "inline"
+ script: |
+ Write-Host "##vso[build.updatebuildnumber]$env:FULLVSTSBUILDNUMBER"
+ failOnStderr: "true"
+ condition: "always()"
+
+- task: PowerShell@2
+ displayName: "Build source-build"
+ inputs:
+ targetType: "inline"
+ script: |
+ ./eng/source-build/build.sh
+ condition: "always()"
+
+- task: PublishBuildArtifacts@1
+ displayName: Upload source-build log
+ condition: "always()"
+ continueOnError: true
+ inputs:
+ PathToPublish: "artifacts/source-build/self/log/source-build.binlog"
+ ArtifactName: "Source-build log"
+ ArtifactType: Container
+
diff --git a/eng/pipelines/templates/pipeline.yml b/eng/pipelines/templates/pipeline.yml
index f7d04b67076..ba4a3417360 100644
--- a/eng/pipelines/templates/pipeline.yml
+++ b/eng/pipelines/templates/pipeline.yml
@@ -166,3 +166,18 @@ jobs:
steps:
- template: Apex_Tests_On_Windows.yml
+
+- job: Source_Build
+ dependsOn:
+ - Initialize_Build
+ timeoutInMinutes: 120
+ variables:
+ BuildNumber: $[dependencies.Initialize_Build.outputs['updatebuildnumber.BuildNumber']]
+ FullVstsBuildNumber: $[dependencies.Initialize_Build.outputs['updatebuildnumber.FullVstsBuildNumber']]
+ SDKVersionForBuild: $[dependencies.Initialize_Build.outputs['getSDKVersionForBuild.SDKVersionForBuild']]
+ BuildRTM: "false"
+ pool:
+ vmImage: ubuntu-latest
+ demands: sh
+ steps:
+ - template: Source_Build.yml
diff --git a/eng/source-build-patches/0001-Rename-NuGet.Config-to-NuGet.config-to-account-for-a.patch b/eng/source-build-patches/0001-Rename-NuGet.Config-to-NuGet.config-to-account-for-a.patch
new file mode 100644
index 00000000000..723a20432cf
--- /dev/null
+++ b/eng/source-build-patches/0001-Rename-NuGet.Config-to-NuGet.config-to-account-for-a.patch
@@ -0,0 +1,18 @@
+From 4743459f7b61cb6a43e23573687e91232afcf06a Mon Sep 17 00:00:00 2001
+From: Chris Rummel
+Date: Mon, 21 Jun 2021 15:11:21 -0500
+Subject: [PATCH] Rename NuGet.Config to NuGet.config to account for an Arcade
+ issue.
+
+---
+ NuGet.Config => NuGet.config | 0
+ 1 file changed, 0 insertions(+), 0 deletions(-)
+ rename NuGet.Config => NuGet.config (100%)
+
+diff --git a/NuGet.Config b/NuGet.config
+similarity index 100%
+rename from NuGet.Config
+rename to NuGet.config
+--
+2.18.0
+
diff --git a/eng/source-build/build.sh b/eng/source-build/build.sh
new file mode 100755
index 00000000000..3bb69b2b00c
--- /dev/null
+++ b/eng/source-build/build.sh
@@ -0,0 +1,47 @@
+#!/usr/bin/env bash
+
+source="${BASH_SOURCE[0]}"
+scriptroot="$( cd -P "$( dirname "$source" )" && pwd )"
+
+# resolve $SOURCE until the file is no longer a symlink
+while [[ -h $source ]]; do
+ scriptroot="$( cd -P "$( dirname "$source" )" && pwd )"
+ source="$(readlink "$source")"
+
+ # if $source was a relative symlink, we need to resolve it relative to the path where the
+ # symlink file was located
+ [[ $source != /* ]] && source="$scriptroot/$source"
+done
+
+function ReadGlobalVersion {
+ local key=$1
+ local global_json_file="$scriptroot/global.json"
+
+ if command -v jq &> /dev/null; then
+ _ReadGlobalVersion="$(jq -r ".[] | select(has(\"$key\")) | .\"$key\"" "$global_json_file")"
+ elif [[ "$(cat "$global_json_file")" =~ \"$key\"[[:space:]\:]*\"([^\"]+) ]]; then
+ _ReadGlobalVersion=${BASH_REMATCH[1]}
+ fi
+
+ if [[ -z "$_ReadGlobalVersion" ]]; then
+ Write-PipelineTelemetryError -category 'Build' "Error: Cannot find \"$key\" in $global_json_file"
+ ExitWithExitCode 1
+ fi
+}
+
+function GetNuGetPackageCachePath {
+ if [[ -z ${NUGET_PACKAGES:-} ]]; then
+ if [[ "$use_global_nuget_cache" == true ]]; then
+ export NUGET_PACKAGES="$HOME/.nuget/packages"
+ else
+ export NUGET_PACKAGES="$repo_root/.packages"
+ export RESTORENOCACHE=true
+ fi
+ fi
+}
+
+export DOTNET=${DOTNET:-dotnet}
+
+ReadGlobalVersion Microsoft.DotNet.Arcade.Sdk
+export ARCADE_VERSION=$_ReadGlobalVersion
+"$DOTNET" msbuild "$scriptroot/source-build.proj" /p:DotNetBuildFromSource=true /p:ArcadeBuildFromSource=true "/p:RepoRoot=$scriptroot/../../" "/bl:$scriptroot/../../artifacts/source-build/self/log/source-build.binlog"
diff --git a/eng/source-build/global.json b/eng/source-build/global.json
new file mode 100644
index 00000000000..2217a9433a5
--- /dev/null
+++ b/eng/source-build/global.json
@@ -0,0 +1,5 @@
+{
+ "msbuild-sdks": {
+ "Microsoft.DotNet.Arcade.Sdk": "6.0.0-beta.21309.7"
+ }
+}
diff --git a/eng/source-build/source-build.proj b/eng/source-build/source-build.proj
new file mode 100644
index 00000000000..6f90f97935b
--- /dev/null
+++ b/eng/source-build/source-build.proj
@@ -0,0 +1,65 @@
+
+
+
+
+
+ $(MSBuildThisFileDirectory)../../
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/global.json b/global.json
new file mode 100644
index 00000000000..ee4ee7d5f61
--- /dev/null
+++ b/global.json
@@ -0,0 +1,9 @@
+{
+ // This empty file has no effect and is here to support Arcade-powered source-build.
+ // The Arcade build process requires a global.json at the root of the repo and normally
+ // uses it to restore the necessary SDK and tools to build the repo.
+ // However, NuGet explitcly wants to use the ambient SDK (normally latest), not any particular
+ // version. We also don't want to introduce MS.DN.Arcade.SDK into the non-source-build build.
+ // eng/source-build/global.json has the entry for the Arcade version we need for
+ // Arcade-powered source-build.
+}
diff --git a/src/NuGet.Clients/NuGet.SolutionRestoreManager/NuGet.SolutionRestoreManager.csproj b/src/NuGet.Clients/NuGet.SolutionRestoreManager/NuGet.SolutionRestoreManager.csproj
index d51dfd606ba..2039a6877f7 100644
--- a/src/NuGet.Clients/NuGet.SolutionRestoreManager/NuGet.SolutionRestoreManager.csproj
+++ b/src/NuGet.Clients/NuGet.SolutionRestoreManager/NuGet.SolutionRestoreManager.csproj
@@ -169,5 +169,5 @@ using Microsoft.VisualStudio.Shell;
-
+
diff --git a/src/NuGet.Clients/NuGet.Tools/NuGet.Tools.csproj b/src/NuGet.Clients/NuGet.Tools/NuGet.Tools.csproj
index 59b70b496c1..26b202b9250 100644
--- a/src/NuGet.Clients/NuGet.Tools/NuGet.Tools.csproj
+++ b/src/NuGet.Clients/NuGet.Tools/NuGet.Tools.csproj
@@ -183,5 +183,5 @@ using Microsoft.VisualStudio.Shell;
-
+
diff --git a/src/NuGet.Clients/NuGet.VisualStudio.OnlineEnvironment.Client/NuGet.VisualStudio.OnlineEnvironment.Client.csproj b/src/NuGet.Clients/NuGet.VisualStudio.OnlineEnvironment.Client/NuGet.VisualStudio.OnlineEnvironment.Client.csproj
index 0f67cc49637..0d58b275211 100644
--- a/src/NuGet.Clients/NuGet.VisualStudio.OnlineEnvironment.Client/NuGet.VisualStudio.OnlineEnvironment.Client.csproj
+++ b/src/NuGet.Clients/NuGet.VisualStudio.OnlineEnvironment.Client/NuGet.VisualStudio.OnlineEnvironment.Client.csproj
@@ -121,5 +121,5 @@
-
+