diff --git a/Directory.Build.props b/Directory.Build.props
deleted file mode 100644
index ab09286..0000000
--- a/Directory.Build.props
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
- 3.0.0.0
- $(AssemblyVersion)
- $(AssemblyVersion)
-
-
-
diff --git a/FunctionsSdk.sln b/FunctionsSdk.sln
index 0815f4b..78da388 100644
--- a/FunctionsSdk.sln
+++ b/FunctionsSdk.sln
@@ -7,7 +7,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{14D6456E-2F9
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{9B6D0171-3FFD-4892-B407-B633CA4E6712}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.NET.Sdk.Functions.Generator.Tests", "test\Microsoft.NET.Sdk.Functions.Generator.Tests\Microsoft.NET.Sdk.Functions.Generator.Tests.csproj", "{9D59910B-B90E-4BBE-BD26-C2CBF85D37E1}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.NET.Sdk.Functions.Generator.Tests", "test\Microsoft.NET.Sdk.Functions.Generator.Tests\Microsoft.NET.Sdk.Functions.Generator.Tests.csproj", "{9D59910B-B90E-4BBE-BD26-C2CBF85D37E1}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "pack", "pack", "{8D555953-A625-4C7F-93A7-C737644820AB}"
EndProject
@@ -25,6 +25,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.NET.Sdk.Functions
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.NET.Sdk.Functions.MSBuild", "src\Microsoft.NET.Sdk.Functions.MSBuild\Microsoft.NET.Sdk.Functions.MSBuild.csproj", "{1DB38EB5-DBA9-4678-BB99-2BCD1255DDBE}"
EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.NET.Sdk.Functions.EndToEnd.Tests", "test\Microsoft.NET.Sdk.Functions.EndToEnd.Tests\Microsoft.NET.Sdk.Functions.EndToEnd.Tests.csproj", "{3F8DD976-ABCC-4B6B-B991-CEAAA4C03736}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -51,6 +53,10 @@ Global
{1DB38EB5-DBA9-4678-BB99-2BCD1255DDBE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1DB38EB5-DBA9-4678-BB99-2BCD1255DDBE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1DB38EB5-DBA9-4678-BB99-2BCD1255DDBE}.Release|Any CPU.Build.0 = Release|Any CPU
+ {3F8DD976-ABCC-4B6B-B991-CEAAA4C03736}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {3F8DD976-ABCC-4B6B-B991-CEAAA4C03736}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {3F8DD976-ABCC-4B6B-B991-CEAAA4C03736}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {3F8DD976-ABCC-4B6B-B991-CEAAA4C03736}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -61,6 +67,7 @@ Global
{6CEDE940-9F0A-4B2A-97D4-D1EEEE42AF35} = {14D6456E-2F9D-4483-A378-03701A6EB12D}
{B80DA350-8A69-4CD2-9E60-01C51B5A8633} = {9B6D0171-3FFD-4892-B407-B633CA4E6712}
{1DB38EB5-DBA9-4678-BB99-2BCD1255DDBE} = {14D6456E-2F9D-4483-A378-03701A6EB12D}
+ {3F8DD976-ABCC-4B6B-B991-CEAAA4C03736} = {9B6D0171-3FFD-4892-B407-B633CA4E6712}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {DA731A15-774F-46C2-B8DF-298F828DCC2A}
diff --git a/appveyor.cmd b/appveyor.cmd
index 6e8c4bb..49634ba 100644
--- a/appveyor.cmd
+++ b/appveyor.cmd
@@ -1,4 +1,4 @@
powershell Invoke-WebRequest -Uri 'https://dot.net/v1/dotnet-install.ps1' -UseBasicParsing -OutFile '%TEMP%\dotnet-install.ps1'
-powershell %TEMP%\dotnet-install.ps1 -Architecture x64 -Version '3.0.100' -InstallDir '%ProgramFiles%\dotnet'
+powershell %TEMP%\dotnet-install.ps1 -Architecture x64 -Version '3.1.301' -InstallDir '%ProgramFiles%\dotnet'
.paket\paket.exe install
packages\FAKE\tools\fake .\build.fsx
\ No newline at end of file
diff --git a/build.fsx b/build.fsx
index 4c81270..9f385fb 100644
--- a/build.fsx
+++ b/build.fsx
@@ -57,6 +57,7 @@ Target "Build" (fun _ ->
Configuration = "Release"})
)
+
Target "UnitTest" (fun _ ->
DotNetCli.Test (fun p ->
{p with
@@ -67,16 +68,22 @@ Target "UnitTest" (fun _ ->
{p with
Project = "test\\Microsoft.NET.Sdk.Functions.MSBuild.Tests"
Configuration = "Debug"})
+
+ DotNetCli.Test (fun p ->
+ {p with
+ Project = "test\\Microsoft.NET.Sdk.Functions.EndToEnd.Tests"
+ Configuration = "Debug"
+ AdditionalArgs=["--logger"; "console;verbosity=detailed"]})
)
Target "GenerateZipToSign" (fun _ ->
- !! (packOutputPath @@ "netcoreapp3.0\\Microsoft.NET.Sdk.Functions.dll")
+ !! (packOutputPath @@ "netcoreapp3.1\\Microsoft.NET.Sdk.Functions.dll")
++ (buildTaskOutputPath @@ "netstandard2.0\\Microsoft.NET.Sdk.Functions.MSBuild.dll")
- ++ (generatorOutputPath @@ "netcoreapp3.0\\Microsoft.NET.Sdk.Functions.Generator.dll")
+ ++ (generatorOutputPath @@ "netcoreapp3.1\\Microsoft.NET.Sdk.Functions.Generator.dll")
|> CreateZip "." (version + "netstandard2.zip") "" 7 true
- !! (generatorOutputPath @@ "netcoreapp3.0\\Newtonsoft.Json.dll")
- ++ (generatorOutputPath @@ "netcoreapp3.0\\Mono.Cecil.dll")
+ !! (generatorOutputPath @@ "netcoreapp3.1\\Newtonsoft.Json.dll")
+ ++ (generatorOutputPath @@ "netcoreapp3.1\\Mono.Cecil.dll")
|> CreateZip "." (version + "netstandard2thirdparty.zip") "" 7 true
)
@@ -126,9 +133,9 @@ Target "WaitForSigning" (fun _ ->
match signed with
| Success file ->
Unzip "tmpBuild" file
- MoveFileTo ("tmpBuild" @@ "Microsoft.NET.Sdk.Functions.dll", packOutputPath @@ "netcoreapp3.0\\Microsoft.NET.Sdk.Functions.dll")
+ MoveFileTo ("tmpBuild" @@ "Microsoft.NET.Sdk.Functions.dll", packOutputPath @@ "netcoreapp3.1\\Microsoft.NET.Sdk.Functions.dll")
MoveFileTo ("tmpBuild" @@ "Microsoft.NET.Sdk.Functions.MSBuild.dll", buildTaskOutputPath @@ "netstandard2.0\\Microsoft.NET.Sdk.Functions.MSBuild.dll")
- MoveFileTo ("tmpBuild" @@ "Microsoft.NET.Sdk.Functions.Generator.dll", generatorOutputPath @@ "netcoreapp3.0\\Microsoft.NET.Sdk.Functions.Generator.dll")
+ MoveFileTo ("tmpBuild" @@ "Microsoft.NET.Sdk.Functions.Generator.dll", generatorOutputPath @@ "netcoreapp3.1\\Microsoft.NET.Sdk.Functions.Generator.dll")
| Failure e -> targetError e null |> ignore
CleanDir "tmpBuild"
@@ -137,8 +144,8 @@ Target "WaitForSigning" (fun _ ->
match signed with
| Success file ->
Unzip "tmpBuild" file
- MoveFileTo ("tmpBuild" @@ "Newtonsoft.Json.dll", generatorOutputPath @@ "netcoreapp3.0\\Newtonsoft.Json.dll")
- MoveFileTo ("tmpBuild" @@ "Mono.Cecil.dll", generatorOutputPath @@ "netcoreapp3.0\\Mono.Cecil.dll")
+ MoveFileTo ("tmpBuild" @@ "Newtonsoft.Json.dll", generatorOutputPath @@ "netcoreapp3.1\\Newtonsoft.Json.dll")
+ MoveFileTo ("tmpBuild" @@ "Mono.Cecil.dll", generatorOutputPath @@ "netcoreapp3.1\\Mono.Cecil.dll")
| Failure e -> targetError e null |> ignore
)
diff --git a/pack/Microsoft.NET.Sdk.Functions/Microsoft.NET.Sdk.Functions.csproj b/pack/Microsoft.NET.Sdk.Functions/Microsoft.NET.Sdk.Functions.csproj
index 272c81b..73b88e9 100644
--- a/pack/Microsoft.NET.Sdk.Functions/Microsoft.NET.Sdk.Functions.csproj
+++ b/pack/Microsoft.NET.Sdk.Functions/Microsoft.NET.Sdk.Functions.csproj
@@ -4,14 +4,13 @@
- netcoreapp3.0
+ netcoreapp3.1
Microsoft.NET.Sdk.Functions
$(FunctionsSdkVersion)
Microsoft
https://github.com/Azure/azure-functions-vs-build-sdk
https://github.com/Azure/azure-functions-vs-build-sdk
- https://github.com/Azure/azure-functions-vs-build-sdk/blob/master/LICENSE
- https://github.com/Azure/azure-functions-vs-build-sdk/blob/master/LICENSE
+ MIT
https://github.com/Azure/azure-functions-vs-build-sdk
git
azurefunctions
@@ -20,8 +19,8 @@
Build SDK for Azure Functions
true
tools
- ..\..\src\Microsoft.NET.Sdk.Functions.MSBuild\bin\Release
- ..\..\src\Microsoft.NET.Sdk.Functions.Generator\bin\Release
+ ..\..\src\Microsoft.NET.Sdk.Functions.MSBuild\bin\$(Configuration)
+ ..\..\src\Microsoft.NET.Sdk.Functions.Generator\bin\$(Configuration)
false
@@ -44,29 +43,29 @@
true
- tools\netcoreapp3.0\
+ tools\netcoreapp3.1\
-
+
true
- tools\netcoreapp3.0\
+ tools\netcoreapp3.1\
-
+
true
- tools\netcoreapp3.0\
+ tools\netcoreapp3.1\
-
+
true
- tools\netcoreapp3.0\
+ tools\netcoreapp3.1\
-
+
true
- tools\netcoreapp3.0\
+ tools\netcoreapp3.1\
-
+
true
- tools\netcoreapp3.0\
+ tools\netcoreapp3.1\
diff --git a/src/Microsoft.NET.Sdk.Functions.Generator/Microsoft.NET.Sdk.Functions.Generator.csproj b/src/Microsoft.NET.Sdk.Functions.Generator/Microsoft.NET.Sdk.Functions.Generator.csproj
index 030cd2a..3790171 100644
--- a/src/Microsoft.NET.Sdk.Functions.Generator/Microsoft.NET.Sdk.Functions.Generator.csproj
+++ b/src/Microsoft.NET.Sdk.Functions.Generator/Microsoft.NET.Sdk.Functions.Generator.csproj
@@ -1,9 +1,10 @@
-
+
+
- 3.0.0
+ $(FunctionsSdkVersion)
Exe
- netcoreapp3.0
+ netcoreapp3.1
true
Debug
diff --git a/src/Microsoft.NET.Sdk.Functions.MSBuild/Microsoft.NET.Sdk.Functions.MSBuild.csproj b/src/Microsoft.NET.Sdk.Functions.MSBuild/Microsoft.NET.Sdk.Functions.MSBuild.csproj
index 44e50f5..62e7fce 100644
--- a/src/Microsoft.NET.Sdk.Functions.MSBuild/Microsoft.NET.Sdk.Functions.MSBuild.csproj
+++ b/src/Microsoft.NET.Sdk.Functions.MSBuild/Microsoft.NET.Sdk.Functions.MSBuild.csproj
@@ -1,7 +1,8 @@
+
- 3.0.0
+ $(FunctionsSdkVersion)
netstandard2.0
diff --git a/src/Microsoft.NET.Sdk.Functions.MSBuild/Targets/Microsoft.NET.Sdk.Functions.Build.targets b/src/Microsoft.NET.Sdk.Functions.MSBuild/Targets/Microsoft.NET.Sdk.Functions.Build.targets
index e6074cf..a01da3d 100644
--- a/src/Microsoft.NET.Sdk.Functions.MSBuild/Targets/Microsoft.NET.Sdk.Functions.Build.targets
+++ b/src/Microsoft.NET.Sdk.Functions.MSBuild/Targets/Microsoft.NET.Sdk.Functions.Build.targets
@@ -19,20 +19,8 @@ WARNING: DO NOT MODIFY this file unless you are knowledgeable about MSBuild and
============================================================
-->
-
- true
-
-
-
-
-
-
-
-
+ AfterTargets="Build"
+ DependsOnTargets="_FunctionsPostBuildCollectFiles;_FunctionsPostBuildCopyFiles">
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
-
-
+
+
+
diff --git a/src/Microsoft.NET.Sdk.Functions.MSBuild/Targets/Microsoft.NET.Sdk.Functions.Publish.targets b/src/Microsoft.NET.Sdk.Functions.MSBuild/Targets/Microsoft.NET.Sdk.Functions.Publish.targets
index faa8d5e..772a75b 100644
--- a/src/Microsoft.NET.Sdk.Functions.MSBuild/Targets/Microsoft.NET.Sdk.Functions.Publish.targets
+++ b/src/Microsoft.NET.Sdk.Functions.MSBuild/Targets/Microsoft.NET.Sdk.Functions.Publish.targets
@@ -17,22 +17,6 @@ WARNING: DO NOT MODIFY this file unless you are knowledgeable about MSBuild and
-
-
-
+
diff --git a/src/Microsoft.NET.Sdk.Functions.MSBuild/Targets/Microsoft.NET.Sdk.Functions.targets b/src/Microsoft.NET.Sdk.Functions.MSBuild/Targets/Microsoft.NET.Sdk.Functions.targets
index d892ded..7c59a7c 100644
--- a/src/Microsoft.NET.Sdk.Functions.MSBuild/Targets/Microsoft.NET.Sdk.Functions.targets
+++ b/src/Microsoft.NET.Sdk.Functions.MSBuild/Targets/Microsoft.NET.Sdk.Functions.targets
@@ -12,12 +12,13 @@ WARNING: DO NOT MODIFY this file unless you are knowledgeable about MSBuild and
xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <_FunctionsTaskFramework>netcoreapp3.0
+ <_FunctionsTaskFramework>netcoreapp3.1
<_FunctionsTasksDir Condition=" '$(_FunctionsTasksDir)'=='' ">$(MSBuildThisFileDirectory)..\tools\$(_FunctionsTaskFramework)\
<_FunctionsTaskAssemblyFullPath Condition=" '$(_FunctionsTaskAssemblyFullPath)'=='' ">$(_FunctionsTasksDir)\Microsoft.NET.Sdk.Functions.MSBuild.dll
true
pdbonly
- false
+ false
+ true
true
diff --git a/src/Microsoft.NET.Sdk.Functions.MSBuild/Tasks/GenerateFunctions.cs b/src/Microsoft.NET.Sdk.Functions.MSBuild/Tasks/GenerateFunctions.cs
index 652236e..ae0a8f1 100644
--- a/src/Microsoft.NET.Sdk.Functions.MSBuild/Tasks/GenerateFunctions.cs
+++ b/src/Microsoft.NET.Sdk.Functions.MSBuild/Tasks/GenerateFunctions.cs
@@ -6,13 +6,7 @@
namespace Microsoft.NET.Sdk.Functions.Tasks
{
-#if NET46
- [LoadInSeparateAppDomain]
- public class GenerateFunctions : AppDomainIsolatedTask
-#else
-
public class GenerateFunctions : Task
-#endif
{
[Required]
public string TargetPath { get; set; }
@@ -23,18 +17,13 @@ public class GenerateFunctions : Task
[Required]
public string TaskAssemblyDirectory { get; set; }
- public bool UseNETCoreGenerator { get; set; }
-
- public bool UseNETFrameworkGenerator { get; set; }
-
public bool GenerateHostJson { get; set; }
public ITaskItem[] UserProvidedFunctionJsonFiles { get; set; }
public bool FunctionsInDependencies { get; set; }
- private const string NETFrameworkFolder = "net46";
- private const string NETStandardFolder = "netcoreapp3.0";
+ private const string NETCoreAppFolder = "netcoreapp3.1";
public override bool Execute()
{
@@ -47,21 +36,8 @@ public override bool Execute()
string taskDirectoryFullPath = Path.GetFullPath(TaskAssemblyDirectory).TrimEnd(new[] { Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar });
string baseDirectory = Path.GetDirectoryName(taskDirectoryFullPath);
- ProcessStartInfo processStartInfo = null;
-#if NET46
- processStartInfo = GetProcessStartInfo(baseDirectory, isCore: false);
- if (UseNETCoreGenerator)
- {
- processStartInfo = GetProcessStartInfo(baseDirectory, isCore: true);
- }
-#else
- processStartInfo = GetProcessStartInfo(baseDirectory, isCore: true);
- if (UseNETFrameworkGenerator)
- {
- processStartInfo = GetProcessStartInfo(baseDirectory, isCore: false);
- }
+ ProcessStartInfo processStartInfo = GetProcessStartInfo(baseDirectory);
-#endif
this.Log.LogMessage(MessageImportance.Low, $"Function generator path: '{processStartInfo.FileName}'");
this.Log.LogCommandLine(MessageImportance.Low, processStartInfo.Arguments);
using (Process process = new Process { StartInfo = processStartInfo })
@@ -89,11 +65,11 @@ public override bool Execute()
}
}
- private ProcessStartInfo GetProcessStartInfo(string baseLocation, bool isCore)
+ private ProcessStartInfo GetProcessStartInfo(string baseLocation)
{
- string workingDirectory = isCore ? Path.Combine(baseLocation, NETStandardFolder) : Path.Combine(baseLocation, NETFrameworkFolder);
- string exePath = isCore ? DotNetMuxer.MuxerPathOrDefault() : Path.Combine(workingDirectory, "Microsoft.NET.Sdk.Functions.Generator.exe");
- string arguments = isCore ? $"Microsoft.NET.Sdk.Functions.Generator.dll \"{TargetPath} \" \"{OutputPath} \" \"{FunctionsInDependencies} \"" : $"\"{TargetPath} \" \"{OutputPath} \" \"{FunctionsInDependencies} \"";
+ string workingDirectory = Path.Combine(baseLocation, NETCoreAppFolder);
+ string exePath = DotNetMuxer.MuxerPathOrDefault();
+ string arguments = $"Microsoft.NET.Sdk.Functions.Generator.dll \"{TargetPath} \" \"{OutputPath} \" \"{FunctionsInDependencies} \"";
string excludedFunctionNamesArg = UserProvidedFunctionJsonFiles?
.Select(f => f.ItemSpec.Replace("/", @"\").Replace(@"\function.json", string.Empty))
diff --git a/test/Microsoft.NET.Sdk.Functions.EndToEnd.Tests/FunctionsSdkTests.cs b/test/Microsoft.NET.Sdk.Functions.EndToEnd.Tests/FunctionsSdkTests.cs
new file mode 100644
index 0000000..cf8d90e
--- /dev/null
+++ b/test/Microsoft.NET.Sdk.Functions.EndToEnd.Tests/FunctionsSdkTests.cs
@@ -0,0 +1,141 @@
+using System.IO;
+using System.Linq;
+using Xunit;
+using Xunit.Abstractions;
+
+namespace Microsoft.NET.Sdk.Functions.EndToEnd.Tests
+{
+ public class FunctionsSdkTests
+ {
+ private string _packageSource;
+ private string _testsDirectory;
+ private TestInitialize _testInitializer;
+ private ITestOutputHelper _testOutputHelper;
+ public FunctionsSdkTests(ITestOutputHelper output)
+ {
+ _testInitializer = new TestInitialize(output);
+ _testOutputHelper = output;
+ _packageSource = _testInitializer.PackageSource;
+ _testsDirectory = _testInitializer.TestDirectory;
+ }
+
+ [Fact]
+ public void BuildAndPublish_CopiesBinariesToAdditionalBinFolder()
+ {
+ // Name of the csproj
+ string projectFileToTest = "FunctionsSdk";
+ string projectFileDirectory = Path.Combine(_testsDirectory, projectFileToTest);
+
+ // Restore
+ string dotnetArgs = $"restore {projectFileToTest}.csproj --source {_packageSource}";
+ int? exitCode = new ProcessWrapper().RunProcess(TestInitialize.DotNetExecutable, dotnetArgs, projectFileDirectory, out int? _, createDirectoryIfNotExists: false, testOutputHelper: _testOutputHelper);
+ Assert.True(exitCode.HasValue && exitCode.Value == 0);
+
+ // Build
+ dotnetArgs = $"build {projectFileToTest}.csproj --configuration {TestInitialize.Configuration}";
+ exitCode = new ProcessWrapper().RunProcess(TestInitialize.DotNetExecutable, dotnetArgs, projectFileDirectory, out int? _, createDirectoryIfNotExists: false, testOutputHelper: _testOutputHelper);
+ Assert.True(exitCode.HasValue && exitCode.Value == 0);
+
+ string additionalBinDir = Path.Combine(projectFileDirectory, "bin", TestInitialize.Configuration, TestInitialize.Framework, "bin");
+ Assert.True(Directory.Exists(additionalBinDir));
+
+ var files = Directory.EnumerateFiles(additionalBinDir, "*.dll", SearchOption.AllDirectories);
+ Assert.True(files.Count() > 1);
+
+ // Publish
+ dotnetArgs = $"publish {projectFileToTest}.csproj --configuration {TestInitialize.Configuration}";
+ exitCode = new ProcessWrapper().RunProcess(TestInitialize.DotNetExecutable, dotnetArgs, projectFileDirectory, out int? _, createDirectoryIfNotExists: false, testOutputHelper: _testOutputHelper);
+ Assert.True(exitCode.HasValue && exitCode.Value == 0);
+
+ string additionalPublishBinDir = Path.Combine(projectFileDirectory, "bin", TestInitialize.Configuration, TestInitialize.Framework, "publish", "bin");
+ Assert.True(Directory.Exists(additionalPublishBinDir));
+
+ files = Directory.EnumerateFiles(additionalPublishBinDir, "*.dll", SearchOption.AllDirectories);
+ Assert.True(files.Count() > 1);
+ }
+
+ [Fact]
+ public void BuildAndPublish_CopiesRuntimesToAdditionalBinFolder()
+ {
+ // Name of the csproj
+ string projectFileToTest = "FunctionsSdkWithSQLClient";
+ string projectFileDirectory = Path.Combine(_testsDirectory, projectFileToTest);
+
+ // Restore
+ string dotnetArgs = $"restore {projectFileToTest}.csproj --source {TestInitialize.NuGetPackageSource};{_packageSource}";
+ int? exitCode = new ProcessWrapper().RunProcess(TestInitialize.DotNetExecutable, dotnetArgs, projectFileDirectory, out int? _, createDirectoryIfNotExists: false, testOutputHelper: _testOutputHelper);
+ Assert.True(exitCode.HasValue && exitCode.Value == 0);
+
+ // Build
+ dotnetArgs = $"build {projectFileToTest}.csproj --configuration {TestInitialize.Configuration}";
+ exitCode = new ProcessWrapper().RunProcess(TestInitialize.DotNetExecutable, dotnetArgs, projectFileDirectory, out int? _, createDirectoryIfNotExists: false, testOutputHelper: _testOutputHelper);
+ Assert.True(exitCode.HasValue && exitCode.Value == 0);
+
+ string additionalBinDir = Path.Combine(projectFileDirectory, "bin", TestInitialize.Configuration, TestInitialize.Framework, "bin");
+ Assert.True(Directory.Exists(additionalBinDir));
+
+ var files = Directory.EnumerateFiles(additionalBinDir, "*.dll", SearchOption.AllDirectories);
+ Assert.True(files.Count() > 1);
+
+ files = Directory.EnumerateFiles(Path.Combine(additionalBinDir, "runtimes"), "*.dll", SearchOption.AllDirectories);
+ Assert.True(files.Count() > 1);
+
+ // Publish
+ dotnetArgs = $"publish {projectFileToTest}.csproj --configuration {TestInitialize.Configuration}";
+ exitCode = new ProcessWrapper().RunProcess(TestInitialize.DotNetExecutable, dotnetArgs, projectFileDirectory, out int? _, createDirectoryIfNotExists: false, testOutputHelper: _testOutputHelper);
+ Assert.True(exitCode.HasValue && exitCode.Value == 0);
+
+ string additionalPublishBinDir = Path.Combine(projectFileDirectory, "bin", TestInitialize.Configuration, TestInitialize.Framework, "publish", "bin");
+ Assert.True(Directory.Exists(additionalPublishBinDir));
+
+ files = Directory.EnumerateFiles(additionalPublishBinDir, "*.dll", SearchOption.AllDirectories);
+ Assert.True(files.Count() > 1);
+
+ files = Directory.EnumerateFiles(Path.Combine(additionalPublishBinDir, "runtimes"), "*.dll", SearchOption.AllDirectories);
+ Assert.True(files.Count() > 1);
+ }
+
+ [Fact]
+ public void Build_FunctionAppWithHttpTrigger_GeneratedFunction()
+ {
+ // Name of the csproj
+ string projectFileToTest = "FunctionAppWithHttpTrigger";
+ string projectFileDirectory = Path.Combine(_testsDirectory, projectFileToTest);
+
+ // Restore
+ string dotnetArgs = $"restore {projectFileToTest}.csproj --source {_packageSource}";
+ int? exitCode = new ProcessWrapper().RunProcess(TestInitialize.DotNetExecutable, dotnetArgs, projectFileDirectory, out int? _, createDirectoryIfNotExists: false, testOutputHelper: _testOutputHelper);
+ Assert.True(exitCode.HasValue && exitCode.Value == 0);
+
+ // Build
+ dotnetArgs = $"build {projectFileToTest}.csproj --configuration {TestInitialize.Configuration}";
+ exitCode = new ProcessWrapper().RunProcess(TestInitialize.DotNetExecutable, dotnetArgs, projectFileDirectory, out int? _, createDirectoryIfNotExists: false, testOutputHelper: _testOutputHelper);
+ Assert.True(exitCode.HasValue && exitCode.Value == 0);
+
+ string binDir = Path.Combine(projectFileDirectory, "bin", TestInitialize.Configuration, TestInitialize.Framework);
+ string additionalBinDir = Path.Combine(binDir, "bin");
+ Assert.True(Directory.Exists(additionalBinDir));
+ var files = Directory.EnumerateFiles(additionalBinDir, "*.dll", SearchOption.AllDirectories);
+ Assert.True(files.Count() > 1);
+
+ // Check if the http function is generated
+ string httpTriggerFunctionpath = Path.Combine(binDir, "HttpFunction", "function.json");
+ Assert.True(File.Exists(httpTriggerFunctionpath));
+
+ // Publish
+ dotnetArgs = $"publish {projectFileToTest}.csproj --configuration {TestInitialize.Configuration}";
+ exitCode = new ProcessWrapper().RunProcess(TestInitialize.DotNetExecutable, dotnetArgs, projectFileDirectory, out int? _, createDirectoryIfNotExists: false, testOutputHelper: _testOutputHelper);
+ Assert.True(exitCode.HasValue && exitCode.Value == 0);
+
+ string publishDir = Path.Combine(projectFileDirectory, "bin", TestInitialize.Configuration, TestInitialize.Framework, "publish");
+ string additionalPublishBinDir = Path.Combine(publishDir, "bin");
+ Assert.True(Directory.Exists(additionalPublishBinDir));
+
+ files = Directory.EnumerateFiles(additionalPublishBinDir, "*.dll", SearchOption.AllDirectories);
+ Assert.True(files.Count() > 1);
+
+ httpTriggerFunctionpath = Path.Combine(publishDir, "HttpFunction", "function.json");
+ Assert.True(File.Exists(httpTriggerFunctionpath));
+ }
+ }
+}
diff --git a/test/Microsoft.NET.Sdk.Functions.EndToEnd.Tests/Microsoft.NET.Sdk.Functions.EndToEnd.Tests.csproj b/test/Microsoft.NET.Sdk.Functions.EndToEnd.Tests/Microsoft.NET.Sdk.Functions.EndToEnd.Tests.csproj
new file mode 100644
index 0000000..66d424b
--- /dev/null
+++ b/test/Microsoft.NET.Sdk.Functions.EndToEnd.Tests/Microsoft.NET.Sdk.Functions.EndToEnd.Tests.csproj
@@ -0,0 +1,22 @@
+
+
+
+ netcoreapp3.1
+
+
+
+
+
+
+
+
+
+ Always
+
+
+
+
+
+
+
+
diff --git a/test/Microsoft.NET.Sdk.Functions.EndToEnd.Tests/ProcessWrapper.cs b/test/Microsoft.NET.Sdk.Functions.EndToEnd.Tests/ProcessWrapper.cs
new file mode 100644
index 0000000..4498f45
--- /dev/null
+++ b/test/Microsoft.NET.Sdk.Functions.EndToEnd.Tests/ProcessWrapper.cs
@@ -0,0 +1,46 @@
+using System;
+using System.Diagnostics;
+using System.IO;
+using Xunit.Abstractions;
+
+namespace Microsoft.NET.Sdk.Functions.EndToEnd.Tests
+{
+ public class ProcessWrapper
+ {
+ public int? RunProcess(string fileName, string arguments, string workingDirectory, out int? processId, bool createDirectoryIfNotExists = true, bool waitForExit = true, ITestOutputHelper testOutputHelper = null)
+ {
+ if (createDirectoryIfNotExists && !Directory.Exists(workingDirectory))
+ {
+ Directory.CreateDirectory(workingDirectory);
+ }
+
+ ProcessStartInfo startInfo = new ProcessStartInfo
+ {
+ CreateNoWindow = true,
+ UseShellExecute = false,
+ WorkingDirectory = workingDirectory,
+ FileName = fileName,
+ RedirectStandardError = true,
+ RedirectStandardOutput = true,
+ };
+ if (!string.IsNullOrEmpty(arguments))
+ {
+ startInfo.Arguments = arguments;
+ }
+
+ Process testProcess = Process.Start(startInfo);
+ processId = testProcess?.Id;
+ if (waitForExit)
+ {
+ testProcess.WaitForExit(3 * 60 * 1000);
+ var standardOut = testProcess.StandardOutput.ReadToEnd();
+ var standardError = testProcess.StandardError.ReadToEnd();
+ testOutputHelper?.WriteLine(standardOut);
+ testOutputHelper?.WriteLine(standardError);
+ return testProcess?.ExitCode;
+ }
+
+ return -1;
+ }
+ }
+}
diff --git a/test/Microsoft.NET.Sdk.Functions.EndToEnd.Tests/Resources/FunctionAppWithHttpTrigger/FunctionAppWithHttpTrigger.csproj b/test/Microsoft.NET.Sdk.Functions.EndToEnd.Tests/Resources/FunctionAppWithHttpTrigger/FunctionAppWithHttpTrigger.csproj
new file mode 100644
index 0000000..7380a99
--- /dev/null
+++ b/test/Microsoft.NET.Sdk.Functions.EndToEnd.Tests/Resources/FunctionAppWithHttpTrigger/FunctionAppWithHttpTrigger.csproj
@@ -0,0 +1,23 @@
+
+
+
+
+ netcoreapp3.1
+ v3
+
+
+
+
+
+
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+ Never
+
+
+
+
\ No newline at end of file
diff --git a/test/Microsoft.NET.Sdk.Functions.EndToEnd.Tests/Resources/FunctionAppWithHttpTrigger/HttpFunction.cs b/test/Microsoft.NET.Sdk.Functions.EndToEnd.Tests/Resources/FunctionAppWithHttpTrigger/HttpFunction.cs
new file mode 100644
index 0000000..ae2ea34
--- /dev/null
+++ b/test/Microsoft.NET.Sdk.Functions.EndToEnd.Tests/Resources/FunctionAppWithHttpTrigger/HttpFunction.cs
@@ -0,0 +1,35 @@
+using System;
+using System.IO;
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.Azure.WebJobs;
+using Microsoft.Azure.WebJobs.Extensions.Http;
+using Microsoft.AspNetCore.Http;
+using Microsoft.Extensions.Logging;
+using Newtonsoft.Json;
+
+namespace FunctionApp1
+{
+ public static class HttpFunction
+ {
+ [FunctionName("HttpFunction")]
+ public static async Task Run(
+ [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req,
+ ILogger log)
+ {
+ log.LogInformation("C# HTTP trigger function processed a request.");
+
+ string name = req.Query["name"];
+
+ string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
+ dynamic data = JsonConvert.DeserializeObject(requestBody);
+ name = name ?? data?.name;
+
+ string responseMessage = string.IsNullOrEmpty(name)
+ ? "This HTTP triggered function executed successfully. Pass a name in the query string or in the request body for a personalized response."
+ : $"Hello, {name}. This HTTP triggered function executed successfully.";
+
+ return new OkObjectResult(responseMessage);
+ }
+ }
+}
diff --git a/test/Microsoft.NET.Sdk.Functions.EndToEnd.Tests/Resources/FunctionAppWithHttpTrigger/host.json b/test/Microsoft.NET.Sdk.Functions.EndToEnd.Tests/Resources/FunctionAppWithHttpTrigger/host.json
new file mode 100644
index 0000000..bb3b8da
--- /dev/null
+++ b/test/Microsoft.NET.Sdk.Functions.EndToEnd.Tests/Resources/FunctionAppWithHttpTrigger/host.json
@@ -0,0 +1,11 @@
+{
+ "version": "2.0",
+ "logging": {
+ "applicationInsights": {
+ "samplingExcludedTypes": "Request",
+ "samplingSettings": {
+ "isEnabled": true
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/Microsoft.NET.Sdk.Functions.EndToEnd.Tests/Resources/FunctionAppWithHttpTrigger/local.settings.json b/test/Microsoft.NET.Sdk.Functions.EndToEnd.Tests/Resources/FunctionAppWithHttpTrigger/local.settings.json
new file mode 100644
index 0000000..4fce9ff
--- /dev/null
+++ b/test/Microsoft.NET.Sdk.Functions.EndToEnd.Tests/Resources/FunctionAppWithHttpTrigger/local.settings.json
@@ -0,0 +1,7 @@
+{
+ "IsEncrypted": false,
+ "Values": {
+ "AzureWebJobsStorage": "UseDevelopmentStorage=true",
+ "FUNCTIONS_WORKER_RUNTIME": "dotnet"
+ }
+}
\ No newline at end of file
diff --git a/test/Microsoft.NET.Sdk.Functions.EndToEnd.Tests/Resources/FunctionsSdk/FunctionsSdk.csproj b/test/Microsoft.NET.Sdk.Functions.EndToEnd.Tests/Resources/FunctionsSdk/FunctionsSdk.csproj
new file mode 100644
index 0000000..a4c317b
--- /dev/null
+++ b/test/Microsoft.NET.Sdk.Functions.EndToEnd.Tests/Resources/FunctionsSdk/FunctionsSdk.csproj
@@ -0,0 +1,13 @@
+
+
+
+
+ netcoreapp3.1
+ v3
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/test/Microsoft.NET.Sdk.Functions.EndToEnd.Tests/Resources/FunctionsSdkWithSQLClient/FunctionsSdkWithSQlClient.csproj b/test/Microsoft.NET.Sdk.Functions.EndToEnd.Tests/Resources/FunctionsSdkWithSQLClient/FunctionsSdkWithSQlClient.csproj
new file mode 100644
index 0000000..4f7e7b2
--- /dev/null
+++ b/test/Microsoft.NET.Sdk.Functions.EndToEnd.Tests/Resources/FunctionsSdkWithSQLClient/FunctionsSdkWithSQlClient.csproj
@@ -0,0 +1,13 @@
+
+
+
+
+ netcoreapp3.1
+ v3
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/test/Microsoft.NET.Sdk.Functions.EndToEnd.Tests/TestInitialize.cs b/test/Microsoft.NET.Sdk.Functions.EndToEnd.Tests/TestInitialize.cs
new file mode 100644
index 0000000..dbd667a
--- /dev/null
+++ b/test/Microsoft.NET.Sdk.Functions.EndToEnd.Tests/TestInitialize.cs
@@ -0,0 +1,100 @@
+using System;
+using System.Diagnostics;
+using System.IO;
+using System.Linq;
+using Xunit;
+using Xunit.Abstractions;
+
+namespace Microsoft.NET.Sdk.Functions.EndToEnd.Tests
+{
+ public class TestInitialize
+ {
+ public const string TestProjectsSourceDirectory = "Resources";
+ public const string TestProjectsTargetDirectory = "TestResults";
+ public const string FunctionsNetSdkProject = "Microsoft.Net.Sdk.Functions";
+ public const string FunctionsMsBuildProject = "Microsoft.NET.Sdk.Functions.MSBuild";
+ public const string FunctionsGeneratorProject = "Microsoft.NET.Sdk.Functions.Generator";
+ public const string Configuration = "Debug";
+ public const string Framework = "netcoreapp3.1";
+ public const string NuGetPackageSource = @"https://api.nuget.org/v3/index.json";
+
+ public static readonly string DotNetExecutable = "dotnet";
+ public static readonly string PathToRepoRoot = Path.GetFullPath(Path.Combine(AppContext.BaseDirectory, @"..\..\..\..\..\"));
+ public static readonly string SrcRoot = Path.Combine(PathToRepoRoot, "src");
+ public static readonly string PackRoot = Path.Combine(PathToRepoRoot, "pack");
+ public static readonly string TestRoot = Path.Combine(PathToRepoRoot, "test");
+
+ public string PackageSource { get; private set; }
+ public string TestDirectory { get; private set; }
+
+ public TestInitialize(ITestOutputHelper testOutputHelper, bool runRestore = false, bool runBuild = false, bool runPack = true)
+ {
+ string dotnetArgs;
+ int? exitCode;
+ string projectDir = Path.Combine(PackRoot, FunctionsNetSdkProject);
+
+ if (runRestore)
+ {
+ // Run dotnet restore at solution root.
+ dotnetArgs = $"restore";
+ exitCode = new ProcessWrapper().RunProcess(DotNetExecutable, dotnetArgs, PathToRepoRoot, out int? _, createDirectoryIfNotExists: false, testOutputHelper: testOutputHelper);
+ Debug.Assert(exitCode.HasValue && exitCode.Value == 0);
+ }
+
+ if (runBuild)
+ {
+ dotnetArgs = $"build --configuration {Configuration}";
+
+ // Build the functions msbuild project.
+ projectDir = Path.Combine(SrcRoot, FunctionsMsBuildProject);
+ exitCode = new ProcessWrapper().RunProcess(DotNetExecutable, dotnetArgs, projectDir, out int? _, createDirectoryIfNotExists: false, testOutputHelper: testOutputHelper);
+ Debug.Assert(exitCode.HasValue && exitCode.Value == 0);
+
+ // Build the functions generator project.
+ projectDir = Path.Combine(SrcRoot, FunctionsGeneratorProject);
+ exitCode = new ProcessWrapper().RunProcess(DotNetExecutable, dotnetArgs, projectDir, out _, createDirectoryIfNotExists: false, testOutputHelper: testOutputHelper);
+ Debug.Assert(exitCode.HasValue && exitCode.Value == 0);
+ }
+
+ if (runPack)
+ {
+ dotnetArgs = $"pack --configuration {Configuration}";
+
+ // Create the package
+ projectDir = Path.Combine(PackRoot, FunctionsNetSdkProject);
+ exitCode = new ProcessWrapper().RunProcess(DotNetExecutable, dotnetArgs, projectDir, out _, createDirectoryIfNotExists: false, testOutputHelper: testOutputHelper);
+ Debug.Assert(exitCode.HasValue && exitCode.Value == 0);
+ }
+
+ // Setup the package source.
+ PackageSource = Path.Combine(projectDir, "bin", Configuration) + Path.DirectorySeparatorChar;
+
+ // Setup the test directory.
+ string sourceDirectory = Path.Combine(AppContext.BaseDirectory, TestProjectsSourceDirectory);
+ DirectoryInfo diSource = new DirectoryInfo(sourceDirectory);
+
+ string targetDirectory = Path.Combine(PathToRepoRoot, TestProjectsTargetDirectory);
+ DirectoryInfo diTarget = new DirectoryInfo(targetDirectory);
+
+ CopyAll(diSource, diTarget);
+ TestDirectory = targetDirectory;
+ }
+
+ private void CopyAll(DirectoryInfo source, DirectoryInfo target)
+ {
+ Directory.CreateDirectory(target.FullName);
+
+ foreach (FileInfo fi in source.GetFiles())
+ {
+ fi.CopyTo(Path.Combine(target.FullName, fi.Name), true);
+ }
+
+ foreach (DirectoryInfo diSourceSubDir in source.GetDirectories())
+ {
+ DirectoryInfo nextTargetSubDir =
+ target.CreateSubdirectory(diSourceSubDir.Name);
+ CopyAll(diSourceSubDir, nextTargetSubDir);
+ }
+ }
+ }
+}
diff --git a/test/Microsoft.NET.Sdk.Functions.Generator.Tests/Microsoft.NET.Sdk.Functions.Generator.Tests.csproj b/test/Microsoft.NET.Sdk.Functions.Generator.Tests/Microsoft.NET.Sdk.Functions.Generator.Tests.csproj
index dcd4657..d9dc629 100644
--- a/test/Microsoft.NET.Sdk.Functions.Generator.Tests/Microsoft.NET.Sdk.Functions.Generator.Tests.csproj
+++ b/test/Microsoft.NET.Sdk.Functions.Generator.Tests/Microsoft.NET.Sdk.Functions.Generator.Tests.csproj
@@ -1,7 +1,7 @@
Library
- netcoreapp3.0
+ netcoreapp3.1
true
PublicKey.snk
true
diff --git a/test/Microsoft.NET.Sdk.Functions.MSBuild.Tests/Microsoft.NET.Sdk.Functions.MSBuild.Tests.csproj b/test/Microsoft.NET.Sdk.Functions.MSBuild.Tests/Microsoft.NET.Sdk.Functions.MSBuild.Tests.csproj
index 038adf6..15a6a09 100644
--- a/test/Microsoft.NET.Sdk.Functions.MSBuild.Tests/Microsoft.NET.Sdk.Functions.MSBuild.Tests.csproj
+++ b/test/Microsoft.NET.Sdk.Functions.MSBuild.Tests/Microsoft.NET.Sdk.Functions.MSBuild.Tests.csproj
@@ -1,7 +1,7 @@
- netcoreapp2.0
+ netcoreapp3.1