Set up CI with Azure Pipelines (#481)

This commit is contained in:
Naren Soni 2020-11-08 04:13:10 -08:00 коммит произвёл GitHub
Родитель 9f5236bb24
Коммит 7b0f1ef0ad
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
30 изменённых файлов: 847 добавлений и 4 удалений

13
FunctionsSdkE2ETests/.gitignore поставляемый Normal file
Просмотреть файл

@ -0,0 +1,13 @@
bin
obj
csx
.vs
.DS_Store
.vscode
*.user
*.suo
*.cscfg
*.Cache
pub_razor

Просмотреть файл

@ -0,0 +1,31 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.29905.134
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DirectRefEMG", "DirectRef\DirectRefEMG\DirectRefEMG.csproj", "{D76D2626-4BD6-495C-A69D-61DBDF330E5C}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SharedStartup", "SharedStartup\SharedStartup.csproj", "{196A4BB6-8FF2-44C9-BF31-D3517140FD3A}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{D76D2626-4BD6-495C-A69D-61DBDF330E5C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D76D2626-4BD6-495C-A69D-61DBDF330E5C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D76D2626-4BD6-495C-A69D-61DBDF330E5C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D76D2626-4BD6-495C-A69D-61DBDF330E5C}.Release|Any CPU.Build.0 = Release|Any CPU
{196A4BB6-8FF2-44C9-BF31-D3517140FD3A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{196A4BB6-8FF2-44C9-BF31-D3517140FD3A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{196A4BB6-8FF2-44C9-BF31-D3517140FD3A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{196A4BB6-8FF2-44C9-BF31-D3517140FD3A}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {124DF235-0912-41B0-97D7-55D136A20206}
EndGlobalSection
EndGlobal

Просмотреть файл

@ -0,0 +1,24 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\SdkVersion.props" />
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<AzureFunctionsVersion>v3</AzureFunctionsVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Azure.Functions.Extensions" Version="1.0.0" />
<PackageReference Include="Microsoft.Azure.WebJobs.Script.ExtensionsMetadataGenerator" Version="$(ExtensionsMetadataGeneratorDirectReferenceVersion)" />
<PackageReference Include="Microsoft.NET.Sdk.Functions" Version="$(MicrosoftNetSdkFunctionsV3PreviousVersion)" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\SharedStartup\SharedStartup.csproj" />
</ItemGroup>
<ItemGroup>
<None Update="host.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="local.settings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToPublishDirectory>Never</CopyToPublishDirectory>
</None>
</ItemGroup>
</Project>

Просмотреть файл

@ -0,0 +1,14 @@
using DirectRefEMG;
using Microsoft.Azure.Functions.Extensions.DependencyInjection;
[assembly: FunctionsStartup(typeof(DirectRefStartup))]
namespace DirectRefEMG
{
public class DirectRefStartup : FunctionsStartup
{
public override void Configure(IFunctionsHostBuilder builder)
{
}
}
}

Просмотреть файл

@ -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 DirectRefEMG
{
public static class Function1
{
[FunctionName("Function1")]
public static async Task<IActionResult> 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);
}
}
}

Просмотреть файл

@ -0,0 +1,3 @@
{
"version": "2.0"
}

Просмотреть файл

@ -0,0 +1,49 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.28307.572
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SharedStartup", "SharedStartup\SharedStartup.csproj", "{E03C8FCA-EF16-4901-B8C2-97E3ED3722A2}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NetCore20", "FrameworkVersions\NetCore20\NetCore20.csproj", "{E079DE00-E96B-47DE-AA40-07454B1AFF71}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NetCore21", "FrameworkVersions\NetCore21\NetCore21.csproj", "{D5EDC07B-5AA4-4426-AEA3-E9B39D263B68}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NetCore22", "FrameworkVersions\NetCore22\NetCore22.csproj", "{112D1C20-2603-40B3-9EC5-2F15F873DAB4}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NetStandard20", "FrameworkVersions\NetStandard20\NetStandard20.csproj", "{C9E23629-4E83-4AAA-97D8-7301BC0FB34C}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{E03C8FCA-EF16-4901-B8C2-97E3ED3722A2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E03C8FCA-EF16-4901-B8C2-97E3ED3722A2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E03C8FCA-EF16-4901-B8C2-97E3ED3722A2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E03C8FCA-EF16-4901-B8C2-97E3ED3722A2}.Release|Any CPU.Build.0 = Release|Any CPU
{E079DE00-E96B-47DE-AA40-07454B1AFF71}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E079DE00-E96B-47DE-AA40-07454B1AFF71}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E079DE00-E96B-47DE-AA40-07454B1AFF71}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E079DE00-E96B-47DE-AA40-07454B1AFF71}.Release|Any CPU.Build.0 = Release|Any CPU
{D5EDC07B-5AA4-4426-AEA3-E9B39D263B68}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D5EDC07B-5AA4-4426-AEA3-E9B39D263B68}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D5EDC07B-5AA4-4426-AEA3-E9B39D263B68}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D5EDC07B-5AA4-4426-AEA3-E9B39D263B68}.Release|Any CPU.Build.0 = Release|Any CPU
{112D1C20-2603-40B3-9EC5-2F15F873DAB4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{112D1C20-2603-40B3-9EC5-2F15F873DAB4}.Debug|Any CPU.Build.0 = Debug|Any CPU
{112D1C20-2603-40B3-9EC5-2F15F873DAB4}.Release|Any CPU.ActiveCfg = Release|Any CPU
{112D1C20-2603-40B3-9EC5-2F15F873DAB4}.Release|Any CPU.Build.0 = Release|Any CPU
{C9E23629-4E83-4AAA-97D8-7301BC0FB34C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C9E23629-4E83-4AAA-97D8-7301BC0FB34C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C9E23629-4E83-4AAA-97D8-7301BC0FB34C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C9E23629-4E83-4AAA-97D8-7301BC0FB34C}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {BF258C1A-DCD2-4BAA-8455-7B391E0F0AD1}
EndGlobalSection
EndGlobal

Просмотреть файл

@ -0,0 +1,69 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.28803.352
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FunctionsSdkE2ETests", "FunctionsSdkE2ETests\FunctionsSdkE2ETests.csproj", "{A980D42F-48BA-4052-BAB2-0032A6B7516F}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "TestProjects", "TestProjects", "{41E8547B-A497-4C51-B648-80DC7FE9A681}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "V3", "V3\V3\V3.csproj", "{1E490BED-97C2-4FE4-9C85-6837FB5C36A0}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DirectRefEMG", "DirectRef\DirectRefEMG\DirectRefEMG.csproj", "{1A5C26E1-09F5-451D-A137-0E65CA38F85C}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{E3EBA50C-BF05-48FB-8D68-555079B759D0}"
ProjectSection(SolutionItems) = preProject
SdkVersion.props = SdkVersion.props
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NoSdkRef", "NoSdkRef\NoSdkRef.csproj", "{BD963FE0-0F9E-4480-AA2D-A1F9C8089327}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RefNotFound", "Razor\RefNotFound\RefNotFound.csproj", "{41E58322-B3F0-4B2D-8B7A-0626BCEBEDA3}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SharedStartup", "SharedStartup\SharedStartup.csproj", "{36AFB021-DBBD-447D-A6FA-78FB3023D191}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{A980D42F-48BA-4052-BAB2-0032A6B7516F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A980D42F-48BA-4052-BAB2-0032A6B7516F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A980D42F-48BA-4052-BAB2-0032A6B7516F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A980D42F-48BA-4052-BAB2-0032A6B7516F}.Release|Any CPU.Build.0 = Release|Any CPU
{1E490BED-97C2-4FE4-9C85-6837FB5C36A0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1E490BED-97C2-4FE4-9C85-6837FB5C36A0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1E490BED-97C2-4FE4-9C85-6837FB5C36A0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1E490BED-97C2-4FE4-9C85-6837FB5C36A0}.Release|Any CPU.Build.0 = Release|Any CPU
{1A5C26E1-09F5-451D-A137-0E65CA38F85C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1A5C26E1-09F5-451D-A137-0E65CA38F85C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1A5C26E1-09F5-451D-A137-0E65CA38F85C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1A5C26E1-09F5-451D-A137-0E65CA38F85C}.Release|Any CPU.Build.0 = Release|Any CPU
{BD963FE0-0F9E-4480-AA2D-A1F9C8089327}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BD963FE0-0F9E-4480-AA2D-A1F9C8089327}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BD963FE0-0F9E-4480-AA2D-A1F9C8089327}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BD963FE0-0F9E-4480-AA2D-A1F9C8089327}.Release|Any CPU.Build.0 = Release|Any CPU
{41E58322-B3F0-4B2D-8B7A-0626BCEBEDA3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{41E58322-B3F0-4B2D-8B7A-0626BCEBEDA3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{41E58322-B3F0-4B2D-8B7A-0626BCEBEDA3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{41E58322-B3F0-4B2D-8B7A-0626BCEBEDA3}.Release|Any CPU.Build.0 = Release|Any CPU
{36AFB021-DBBD-447D-A6FA-78FB3023D191}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{36AFB021-DBBD-447D-A6FA-78FB3023D191}.Debug|Any CPU.Build.0 = Debug|Any CPU
{36AFB021-DBBD-447D-A6FA-78FB3023D191}.Release|Any CPU.ActiveCfg = Release|Any CPU
{36AFB021-DBBD-447D-A6FA-78FB3023D191}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{1E490BED-97C2-4FE4-9C85-6837FB5C36A0} = {41E8547B-A497-4C51-B648-80DC7FE9A681}
{1A5C26E1-09F5-451D-A137-0E65CA38F85C} = {41E8547B-A497-4C51-B648-80DC7FE9A681}
{BD963FE0-0F9E-4480-AA2D-A1F9C8089327} = {41E8547B-A497-4C51-B648-80DC7FE9A681}
{41E58322-B3F0-4B2D-8B7A-0626BCEBEDA3} = {41E8547B-A497-4C51-B648-80DC7FE9A681}
{36AFB021-DBBD-447D-A6FA-78FB3023D191} = {41E8547B-A497-4C51-B648-80DC7FE9A681}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {E0021489-706A-4A64-98FA-2D1DFE28695E}
EndGlobalSection
EndGlobal

Просмотреть файл

@ -0,0 +1,254 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using Newtonsoft.Json.Linq;
using Xunit;
namespace FunctionsSdkE2ETests
{
public class E2ETests
{
private const string _expectedExtensionsJson = "{\"extensions\":[{ \"name\": \"Startup\", \"typeName\":\"SharedStartup.Startup, SharedStartup, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null\"}]}";
private const string _expectedBinFolder = @"\bin";
private void CleanBinFolders(string rootDir)
{
foreach (string binDir in Directory.EnumerateDirectories(rootDir, "bin", new EnumerationOptions { RecurseSubdirectories = true }))
{
Directory.Delete(binDir, true);
}
}
[Fact]
public void Build_DirectRef()
{
string solutionName = "DirectRef";
string solutionFile = solutionName + ".sln";
string workingDir = FindContainingDirectory(solutionFile);
RunDotNet("restore", workingDir, solutionFile);
RunDotNet("clean", workingDir, solutionFile);
RunDotNet("build", workingDir, solutionFile);
ValidateExtensionsJsonRecursive(Path.Combine(workingDir, solutionName), 1, expectedFolder: _expectedBinFolder,
ValidateDirectRefStartupExtension,
ValidateSharedStartupExtension);
}
[Fact]
public void Publish_DirectRef()
{
string publishDir = Path.Combine(Path.GetTempPath(), "FunctionsSdkTests", "pub_directRef");
if (Directory.Exists(publishDir))
{
Directory.Delete(publishDir, true);
}
string solutionName = "DirectRef";
string solutionFile = solutionName + ".sln";
string workingDir = FindContainingDirectory(solutionFile);
RunDotNet("restore", workingDir, solutionFile);
RunDotNet("clean", workingDir, solutionFile);
RunDotNet("publish", workingDir, solutionFile, $"-o {publishDir} /bl");
ValidateExtensionsJsonRecursive(publishDir, 1, expectedFolder: _expectedBinFolder,
ValidateDirectRefStartupExtension,
ValidateSharedStartupExtension);
}
[Fact]
public void Build_NoSdkRef()
{
string solutionName = "NoSdkRef";
string solutionFile = solutionName + ".sln";
string workingDir = FindContainingDirectory(solutionFile);
string projectDir = Path.Combine(workingDir, solutionName);
CleanBinFolders(projectDir);
RunDotNet("restore", workingDir, solutionFile);
RunDotNet("clean", workingDir, solutionFile);
RunDotNet("build", workingDir, solutionFile);
ValidateExtensionsJsonRecursive(projectDir, 1, expectedFolder: @"Debug\netcoreapp2.1",
t =>
{
return t["name"].ToString() == "AzureStorage"
&& t["typeName"].ToString() == "Microsoft.Azure.WebJobs.Extensions.Storage.AzureStorageWebJobsStartup, Microsoft.Azure.WebJobs.Extensions.Storage, Version=3.0.5.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35";
});
}
[Fact]
public void Build_V3()
{
RunBasicValidation("V3");
}
private void RunBasicValidation(string solutionName)
{
string solutionFile = solutionName + ".sln";
string workingDir = FindContainingDirectory(solutionFile);
string projectDir = Path.Combine(workingDir, solutionName);
CleanBinFolders(projectDir);
RunDotNet("restore", workingDir, solutionFile);
RunDotNet("clean", workingDir, solutionFile);
RunDotNet("build", workingDir, solutionFile);
ValidateExtensionsJsonRecursive(projectDir, 1, expectedFolder: _expectedBinFolder,
t =>
{
return t["name"].ToString() == "AzureStorage"
&& t["typeName"].ToString() == "Microsoft.Azure.WebJobs.Extensions.Storage.AzureStorageWebJobsStartup, Microsoft.Azure.WebJobs.Extensions.Storage, Version=3.0.10.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35";
},
t =>
{
return t["name"].ToString() == "Startup"
&& t["typeName"].ToString() == $"{solutionName}.Startup, {solutionName}, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null";
});
// The tests include one auto-created and one manually-created function.json file. The build should generate both into the output folder.
string projectFolder = Path.GetDirectoryName(projectDir);
string projectBinDir = Path.Combine(projectDir, solutionName, "bin");
IEnumerable<string> functionJsonFilePaths = Directory.EnumerateFiles(Path.Combine(projectBinDir), "function.json", new EnumerationOptions { RecurseSubdirectories = true });
// Comment out until 3.0.10 and 1.0.38 are released
// Assert.Collection(functionJsonFilePaths,
// p => Assert.EndsWith("\\Function1\\function.json", p),
// p => Assert.EndsWith("\\Function2\\function.json", p));
}
private void RunTest(string solutionName, int expectedExtensionsJsonCount = 1)
{
string solutionFile = solutionName + ".sln";
string workingDir = FindContainingDirectory(solutionFile);
RunDotNet("restore", workingDir, solutionFile);
RunDotNet("clean", workingDir, solutionFile);
RunDotNet("build", workingDir, solutionFile);
ValidateExtensionsJsonRecursive(Path.Combine(workingDir, solutionName), expectedExtensionsJsonCount);
}
private bool ValidateSharedStartupExtension(JToken extensionToken)
{
return extensionToken["name"].ToString() == "Startup" && extensionToken["typeName"].ToString() == "SharedStartup.Startup, SharedStartup, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null";
}
private bool ValidateDirectRefStartupExtension(JToken extensionToken)
{
return extensionToken["name"].ToString() == "DirectRefStartup" && extensionToken["typeName"].ToString() == "DirectRefEMG.DirectRefStartup, DirectRefEMG, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null";
}
private void ValidateExtensionsJsonRecursive(string startingDir, int expectedCount)
{
ValidateExtensionsJsonRecursive(startingDir, expectedCount, expectedFolder: _expectedBinFolder, ValidateSharedStartupExtension);
}
private void ValidateExtensionsJsonRecursive(string startingDir, int expectedCount, string expectedFolder, params Func<JToken, bool>[] extensionValidators)
{
// Check all extensions.json
IEnumerable<string> extensionsFiles = Directory.EnumerateFiles(Path.Combine(startingDir), "extensions.json", new EnumerationOptions { RecurseSubdirectories = true });
Assert.Equal(expectedCount, extensionsFiles.Count());
foreach (string file in extensionsFiles)
{
Assert.True(Path.GetDirectoryName(file).EndsWith(expectedFolder, StringComparison.OrdinalIgnoreCase), $"'{file}' is not in the '{expectedFolder}' folder");
JObject actualJson = JObject.Parse(File.ReadAllText(file));
JToken[] extensionsArray = actualJson["extensions"]
.AsEnumerable()
.OrderBy(p => p["name"])
.ToArray();
string createErrorMessage()
{
return $"File: {file} | Actual: {actualJson}";
}
Assert.True(extensionValidators.Length == extensionsArray.Length, $"Incorrect number of validators ({extensionValidators.Length}) | {createErrorMessage()}");
for (int i = 0; i < extensionValidators.Length; i++)
{
JToken extension = extensionsArray[i];
Assert.True(extensionValidators[i](extension), $"Failed validator for {extension} | {createErrorMessage()}");
}
}
}
private void RunDotNet(string command, string workingDir, string solutionFile, string additionalArgs = null)
{
ProcessStartInfo startInfo = new ProcessStartInfo
{
WorkingDirectory = workingDir,
FileName = "dotnet",
Arguments = $"{command} {solutionFile} {additionalArgs} -nodeReuse:False",
RedirectStandardError = true,
RedirectStandardOutput = true
};
using (Process process = Process.Start(startInfo))
{
StringBuilder stdOut = new StringBuilder(); ;
StringBuilder stdErr = new StringBuilder();
process.OutputDataReceived += (s, e) =>
{
if (e.Data != null)
{
stdOut.AppendLine(e.Data);
}
};
process.ErrorDataReceived += (s, e) =>
{
if (e.Data != null)
{
stdErr.AppendLine(e.Data);
}
};
process.BeginErrorReadLine();
process.BeginOutputReadLine();
process.WaitForExit();
Assert.True(process.ExitCode == 0, $"StdOut: {stdOut} | StdErr: {stdErr}");
Assert.Empty(stdErr.ToString());
//Assert.DoesNotContain(": warning ", stdOut.ToString());
Assert.DoesNotContain(": error ", stdOut.ToString());
}
}
private string FindContainingDirectory(string fileToFind)
{
string currentDir = Directory.GetCurrentDirectory();
string dir = null;
while (currentDir != null && dir == null)
{
if (Directory.EnumerateFiles(currentDir, fileToFind).SingleOrDefault() != null)
{
dir = currentDir;
}
else
{
currentDir = Directory.GetParent(currentDir)?.FullName;
}
}
return dir;
}
}
}

Просмотреть файл

@ -0,0 +1,20 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>
<ItemGroup>
<None Include="..\SdkVersion.props" Link="SdkVersion.props" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="12.0.2" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.1">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
</Project>

Просмотреть файл

@ -0,0 +1,25 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.29905.134
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NoSdkRef", "NoSdkRef\NoSdkRef.csproj", "{24D545FC-FCBC-4DE7-B94B-821D77C378A6}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{24D545FC-FCBC-4DE7-B94B-821D77C378A6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{24D545FC-FCBC-4DE7-B94B-821D77C378A6}.Debug|Any CPU.Build.0 = Debug|Any CPU
{24D545FC-FCBC-4DE7-B94B-821D77C378A6}.Release|Any CPU.ActiveCfg = Release|Any CPU
{24D545FC-FCBC-4DE7-B94B-821D77C378A6}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {48B5EC69-8C12-406B-943B-C41C5DA3B47F}
EndGlobalSection
EndGlobal

Просмотреть файл

@ -0,0 +1,16 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\SdkVersion.props" />
<PropertyGroup>
<TargetFramework>netcoreapp2.1</TargetFramework>
<AzureFunctionsVersion>v2</AzureFunctionsVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Azure.WebJobs.Extensions.Storage" Version="3.0.5" />
<PackageReference Include="Microsoft.Azure.WebJobs.Script.ExtensionsMetadataGenerator" Version="$(ExtensionsMetadataGeneratorDirectReferenceVersion)" />
</ItemGroup>
<ItemGroup>
<None Update="host.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>

Просмотреть файл

@ -0,0 +1,3 @@
{
"version": "2.0"
}

Просмотреть файл

@ -0,0 +1,37 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.28803.352
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SharedStartup", "SharedStartup\SharedStartup.csproj", "{3BF97B5B-5D0B-49CE-B183-03C0D4E31086}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RefNotFound", "Razor\RefNotFound\RefNotFound.csproj", "{F5122E92-EA3C-4ED5-8D69-541134443E69}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Mvc", "Razor\Mvc\Mvc.csproj", "{4D35EF45-9122-4BB9-B2F3-FEF3DF0C6EF6}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{3BF97B5B-5D0B-49CE-B183-03C0D4E31086}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3BF97B5B-5D0B-49CE-B183-03C0D4E31086}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3BF97B5B-5D0B-49CE-B183-03C0D4E31086}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3BF97B5B-5D0B-49CE-B183-03C0D4E31086}.Release|Any CPU.Build.0 = Release|Any CPU
{F5122E92-EA3C-4ED5-8D69-541134443E69}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F5122E92-EA3C-4ED5-8D69-541134443E69}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F5122E92-EA3C-4ED5-8D69-541134443E69}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F5122E92-EA3C-4ED5-8D69-541134443E69}.Release|Any CPU.Build.0 = Release|Any CPU
{4D35EF45-9122-4BB9-B2F3-FEF3DF0C6EF6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4D35EF45-9122-4BB9-B2F3-FEF3DF0C6EF6}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4D35EF45-9122-4BB9-B2F3-FEF3DF0C6EF6}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4D35EF45-9122-4BB9-B2F3-FEF3DF0C6EF6}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {A9D02ED7-1086-4736-AD7A-9F6DA681C515}
EndGlobalSection
EndGlobal

Просмотреть файл

@ -0,0 +1,22 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\SdkVersion.props"/>
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<AzureFunctionsVersion>v3</AzureFunctionsVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Sdk.Functions" Version="$(MicrosoftNetSdkFunctionsV3Version)" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\SharedStartup\SharedStartup.csproj" />
</ItemGroup>
<ItemGroup>
<None Update="host.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="local.settings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToPublishDirectory>Never</CopyToPublishDirectory>
</None>
</ItemGroup>
</Project>

Просмотреть файл

@ -0,0 +1,3 @@
{
"version": "2.0"
}

Просмотреть файл

@ -0,0 +1,7 @@
{
"IsEncrypted": false,
"Values": {
"AzureWebJobsStorage": "UseDevelopmentStorage=true",
"FUNCTIONS_WORKER_RUNTIME": "dotnet"
}
}

Просмотреть файл

@ -0,0 +1,13 @@
<Project>
<Import Project="..\src\Microsoft.NET.Sdk.Functions.MSBuild\Targets\Microsoft.NET.Sdk.Functions.Version.props"/>
<PropertyGroup>
<!-- These are the latest SDK versions -->
<MicrosoftNetSdkFunctionsV3Version>$(FunctionsSdkVersion)</MicrosoftNetSdkFunctionsV3Version>
<!-- Some tests only roll EMG forward, so keep these one behind the latest -->
<MicrosoftNetSdkFunctionsV3PreviousVersion>3.0.8</MicrosoftNetSdkFunctionsV3PreviousVersion>
<!-- Some tests directly reference EMG; this should be latest -->
<ExtensionsMetadataGeneratorDirectReferenceVersion>1.2.0</ExtensionsMetadataGeneratorDirectReferenceVersion>
</PropertyGroup>
</Project>

Просмотреть файл

@ -0,0 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Azure.Functions.Extensions" Version="1.0.0" />
</ItemGroup>
</Project>

Просмотреть файл

@ -0,0 +1,14 @@
using Microsoft.Azure.Functions.Extensions.DependencyInjection;
using SharedStartup;
[assembly: FunctionsStartup(typeof(Startup))]
namespace SharedStartup
{
public class Startup : FunctionsStartup
{
public override void Configure(IFunctionsHostBuilder builder)
{
}
}
}

Просмотреть файл

@ -0,0 +1,25 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.29905.134
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "V3", "V3\V3\V3.csproj", "{86349AE8-9D48-4489-B99F-022784D5FC03}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{86349AE8-9D48-4489-B99F-022784D5FC03}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{86349AE8-9D48-4489-B99F-022784D5FC03}.Debug|Any CPU.Build.0 = Debug|Any CPU
{86349AE8-9D48-4489-B99F-022784D5FC03}.Release|Any CPU.ActiveCfg = Release|Any CPU
{86349AE8-9D48-4489-B99F-022784D5FC03}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {FD0C4C61-C5EC-4257-A36B-2E95CA156BEF}
EndGlobalSection
EndGlobal

Просмотреть файл

@ -0,0 +1,16 @@
using System;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Host;
using Microsoft.Extensions.Logging;
namespace V3
{
public static class Function1
{
[FunctionName("Function1")]
public static void Run([QueueTrigger("myqueue-items", Connection = "AzureWebJobsStorage")]string myQueueItem, ILogger log)
{
log.LogInformation($"C# Queue trigger function processed: {myQueueItem}");
}
}
}

Просмотреть файл

@ -0,0 +1,13 @@
{
"bindings": [
{
"type": "queueTrigger",
"connection": "AzureWebJobsStorage",
"queueName": "myqueue-items",
"name": "myQueueItem"
}
],
"disabled": false,
"scriptFile": "../bin/V3.dll",
"entryPoint": "V3.Function1.Run"
}

Просмотреть файл

@ -0,0 +1,14 @@
using Microsoft.Azure.Functions.Extensions.DependencyInjection;
using V3;
[assembly: FunctionsStartup(typeof(Startup))]
namespace V3
{
public class Startup : FunctionsStartup
{
public override void Configure(IFunctionsHostBuilder builder)
{
}
}
}

Просмотреть файл

@ -0,0 +1,25 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\SdkVersion.props" />
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<AzureFunctionsVersion>v3</AzureFunctionsVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Azure.Functions.Extensions" Version="1.0.0" />
<PackageReference Include="Microsoft.Azure.WebJobs.Extensions.Storage" Version="3.0.10" />
<PackageReference Include="Microsoft.NET.Sdk.Functions" Version="$(MicrosoftNetSdkFunctionsV3Version)" />
</ItemGroup>
<ItemGroup>
<None Update="Function2\function.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="host.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="local.settings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToPublishDirectory>Never</CopyToPublishDirectory>
</None>
</ItemGroup>
</Project>

Просмотреть файл

@ -0,0 +1,11 @@
{
"version": "2.0",
"logging": {
"applicationInsights": {
"samplingExcludedTypes": "Request",
"samplingSettings": {
"isEnabled": true
}
}
}
}

Просмотреть файл

@ -0,0 +1,7 @@
{
"IsEncrypted": false,
"Values": {
"AzureWebJobsStorage": "UseDevelopmentStorage=true",
"FUNCTIONS_WORKER_RUNTIME": "dotnet"
}
}

Просмотреть файл

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<add key="localSource" value="..\artifacts" />
<add key="nuget.org" value="https://www.nuget.org/api/v2/" />
<add key="azure_app_service_staging" value="https://www.myget.org/F/azure-appservice-staging/api/v2" />
</packageSources>
</configuration>

60
azure-pipelines.yml Normal file
Просмотреть файл

@ -0,0 +1,60 @@
name: $(Build.SourceBranchName)_$(Build.Reason)_$(devops_buildNumber)
trigger:
- v3.x
- main
pool:
vmImage: 'windows-2019'
variables:
devops_buildNumber: $[counter(format(''), 289)]
steps:
- task: UseDotNet@2
displayName: 'Install dotnet v3.x'
inputs:
packageType: 'sdk'
version: '3.1.x'
performMultiLevelLookup: true
- task: CmdLine@2
inputs:
script: |
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.1.301' -InstallDir '%ProgramFiles%\dotnet'
.paket\paket.exe install
packages\FAKE\tools\fake .\build.fsx
env:
FILES_ACCOUNT_KEY: $(FILES_ACCOUNT_KEY)
FILES_ACCOUNT_NAME: $(FILES_ACCOUNT_NAME)
BUILD_VERSION: 1.1.$(devops_buildNumber)
displayName: 'Build'
- task: PowerShell@2
displayName: 'Set dotnet path'
inputs:
targetType: 'inline'
script: |
$infoContent = dotnet --info
$sdkBasePath = $infoContent |
Where-Object {$_ -match 'Base Path:'} |
ForEach-Object {
($_ -replace '\s+Base Path:','').trim()
}
Write-Host "dotnet SDK path: $sdkBasePath"
$dotnetPath = (Get-Item $sdkBasePath).Parent.Parent.FullName
Write-Host "dotnet path: $dotnetPath"
Write-Host "##vso[task.setvariable variable=DotNetPath]$dotnetPath"
- task: DotNetCoreCLI@2
displayName: 'Run End to End tests'
inputs:
command: 'test'
projects: '.\FunctionsSdkE2ETests\FunctionsSdkE2ETests.sln'
arguments: '-v n'
- pwsh: |
Move-Item -Path '$(Build.Repository.LocalPath)\artifacts\Microsoft.NET.Sdk.Functions.*' -Destination '$(Build.ArtifactStagingDirectory)'
displayName: 'Move artifacts'
- task: PublishBuildArtifacts@1
inputs:
PathtoPublish: '$(Build.ArtifactStagingDirectory)'
ArtifactName: 'drop'
publishLocation: 'Container'

Просмотреть файл

@ -31,13 +31,14 @@ let connectionString =
let buildTaskOutputPath = "src\\Microsoft.NET.Sdk.Functions.MSBuild\\bin\\Release"
let generatorOutputPath = "src\\Microsoft.NET.Sdk.Functions.Generator\\bin\\Release"
let packOutputPath = "src\\Microsoft.NET.Sdk.Functions\\bin\\Release"
let version = if isNull appVeyorBuildVersion then "1.0.0.3" else appVeyorBuildVersion
let buildVersion = (env "BUILD_VERSION")
let version = if isNull buildVersion then "1.0.0.3" else buildVersion
Target "Clean" (fun _ ->
if Directory.Exists "tmpBuild" |> not then Directory.CreateDirectory "tmpBuild" |> ignore
if Directory.Exists "deploy" |> not then Directory.CreateDirectory "deploy" |> ignore
if Directory.Exists "artifacts" |> not then Directory.CreateDirectory "artifacts" |> ignore
CleanDir "tmpBuild"
CleanDir "deploy"
CleanDir "artifacts"
)
Target "Build" (fun _ ->
@ -178,7 +179,7 @@ Target "SignNupkg" (fun _ ->
Target "Publish" (fun _ ->
!! (packOutputPath @@ "signed\\Microsoft.NET.Sdk.Functions.*.nupkg")
|> Seq.iter (MoveFile "deploy")
|> Seq.iter (MoveFile "artifacts")
)
Dependencies