diff --git a/build/Microsoft.DotNet.Cli.Test.targets b/build/Microsoft.DotNet.Cli.Test.targets
index 7e232f861..fcbd1a668 100644
--- a/build/Microsoft.DotNet.Cli.Test.targets
+++ b/build/Microsoft.DotNet.Cli.Test.targets
@@ -11,7 +11,8 @@
+ DependsOnTargets="EnsureStageSeparation;
+ BuildTests;">
:
@@ -101,4 +102,9 @@
MsbuildArgs="%(TestPackageProject.MsbuildArgs) /p:SdkNuGetVersion=$(SdkNugetVersion)" />
+
+
+
+
diff --git a/build/Microsoft.DotNet.Cli.tasks b/build/Microsoft.DotNet.Cli.tasks
index 49553a226..89c188c72 100644
--- a/build/Microsoft.DotNet.Cli.tasks
+++ b/build/Microsoft.DotNet.Cli.tasks
@@ -9,6 +9,7 @@
+
diff --git a/build_projects/Microsoft.DotNet.Cli.Build.SelfTest/InvokeWithStage0.proj b/build_projects/Microsoft.DotNet.Cli.Build.SelfTest/InvokeWithStage0.proj
new file mode 100644
index 000000000..4175b21fc
--- /dev/null
+++ b/build_projects/Microsoft.DotNet.Cli.Build.SelfTest/InvokeWithStage0.proj
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/build_projects/Microsoft.DotNet.Cli.Build.SelfTest/InvokeWithStage2.proj b/build_projects/Microsoft.DotNet.Cli.Build.SelfTest/InvokeWithStage2.proj
new file mode 100644
index 000000000..1493128e7
--- /dev/null
+++ b/build_projects/Microsoft.DotNet.Cli.Build.SelfTest/InvokeWithStage2.proj
@@ -0,0 +1,29 @@
+
+
+
+ $([System.IO.Path]::GetDirectoryName($(ToolPath)/))
+
+
+
+ false
+ true
+ false
+ true
+ false
+ true
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/build_projects/dotnet-cli-build/DotNetMSBuild.cs b/build_projects/dotnet-cli-build/DotNetMSBuild.cs
new file mode 100644
index 000000000..c5531b802
--- /dev/null
+++ b/build_projects/dotnet-cli-build/DotNetMSBuild.cs
@@ -0,0 +1,30 @@
+// Copyright (c) .NET Foundation and contributors. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+namespace Microsoft.DotNet.Cli.Build
+{
+ public class DotNetMSBuild : DotNetTool
+ {
+ protected override string Command
+ {
+ get { return "msbuild"; }
+ }
+
+ protected override string Args
+ {
+ get { return $"{GetArguments()}"; }
+ }
+
+ public string Arguments { get; set; }
+
+ private string GetArguments()
+ {
+ if (!string.IsNullOrEmpty(Arguments))
+ {
+ return $"{Arguments}";
+ }
+
+ return null;
+ }
+ }
+}
diff --git a/build_projects/dotnet-cli-build/DotNetTool.cs b/build_projects/dotnet-cli-build/DotNetTool.cs
index d074856b0..cc3d1cd83 100644
--- a/build_projects/dotnet-cli-build/DotNetTool.cs
+++ b/build_projects/dotnet-cli-build/DotNetTool.cs
@@ -1,5 +1,6 @@
// Copyright (c) .NET Foundation and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+using System.Diagnostics;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
@@ -18,6 +19,24 @@ namespace Microsoft.DotNet.Cli.Build
protected abstract string Args { get; }
+ protected override ProcessStartInfo GetProcessStartInfo(
+ string pathToTool,
+ string commandLineCommands,
+ string responseFileSwitch)
+ {
+ var psi = base.GetProcessStartInfo(
+ pathToTool,
+ commandLineCommands,
+ responseFileSwitch);
+
+ foreach (var environmentVariableName in new EnvironmentFilter().GetEnvironmentVariableNamesToRemove())
+ {
+ psi.Environment.Remove(environmentVariableName);
+ }
+
+ return psi;
+ }
+
public string WorkingDirectory { get; set; }
protected override string ToolName
diff --git a/build_projects/dotnet-cli-build/EnvironmentVariableFilter.cs b/build_projects/dotnet-cli-build/EnvironmentVariableFilter.cs
new file mode 100644
index 000000000..d5a7a5acf
--- /dev/null
+++ b/build_projects/dotnet-cli-build/EnvironmentVariableFilter.cs
@@ -0,0 +1,57 @@
+// Copyright (c) .NET Foundation and contributors. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace Microsoft.DotNet.Cli.Build
+{
+ public class EnvironmentFilter
+ {
+ private const string _MSBuildEnvironmentVariablePrefix = "MSBuild";
+ private const string _DotNetEnvironmentVariablePrefix = "DOTNET";
+ private const string _NugetEnvironmentVariablePrefix = "NUGET";
+
+ private IEnumerable _prefixesOfEnvironmentVariablesToRemove = new string []
+ {
+ _MSBuildEnvironmentVariablePrefix,
+ _DotNetEnvironmentVariablePrefix,
+ _NugetEnvironmentVariablePrefix
+ };
+
+ private IEnumerable _environmentVariablesToRemove = new string []
+ {
+ "CscToolExe"
+ };
+
+ private IEnumerable _environmentVariablesToKeep = new string []
+ {
+ "DOTNET_CLI_TELEMETRY_SESSIONID",
+ "DOTNET_RUNTIME_ID",
+ "DOTNET_SKIP_FIRST_TIME_EXPERIENCE",
+ "NUGET_PACKAGES"
+ };
+
+ public IEnumerable GetEnvironmentVariableNamesToRemove()
+ {
+ var allEnvironmentVariableNames = (IEnumerable)Environment
+ .GetEnvironmentVariables()
+ .Keys
+ .Cast();
+
+ var environmentVariablesToRemoveByPrefix = allEnvironmentVariableNames
+ .Where(e => _prefixesOfEnvironmentVariablesToRemove.Any(p => e.StartsWith(p)));
+
+ var environmentVariablesToRemoveByName = allEnvironmentVariableNames
+ .Where(e => _environmentVariablesToRemove.Contains(e));
+
+ var environmentVariablesToRemove = environmentVariablesToRemoveByName
+ .Concat(environmentVariablesToRemoveByPrefix)
+ .Distinct()
+ .Except(_environmentVariablesToKeep);
+
+ return environmentVariablesToRemove;
+ }
+ }
+}