diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json
new file mode 100644
index 0000000..0180b9f
--- /dev/null
+++ b/.config/dotnet-tools.json
@@ -0,0 +1,24 @@
+{
+ "version": 1,
+ "isRoot": true,
+ "tools": {
+ "minver-cli": {
+ "version": "2.2.0",
+ "commands": [
+ "minver"
+ ]
+ },
+ "dotnet-retire": {
+ "version": "4.0.1",
+ "commands": [
+ "dotnet-retire"
+ ]
+ },
+ "gpr": {
+ "version": "0.1.122",
+ "commands": [
+ "gpr"
+ ]
+ }
+ }
+ }
\ No newline at end of file
diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml
index e3c6f54..dcf075b 100644
--- a/.github/workflows/build.yaml
+++ b/.github/workflows/build.yaml
@@ -6,6 +6,18 @@ env:
on: [push]
jobs:
+ vulnerability-scan:
+ runs-on: ubuntu-latest
+ name: ci/github/scan-vulnerabilities
+ container: mcr.microsoft.com/dotnet/core/sdk:3.1-bionic
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v2
+ - name: Scan for Vulnerabilities
+ run: |
+ dotnet tool restore
+ dotnet restore
+ dotnet tool run dotnet-retire
build:
runs-on: ubuntu-latest
steps:
@@ -25,4 +37,43 @@ jobs:
with:
name: functions
path: ${{ env.OUTPUT_PATH }}
+ publish:
+ needs: [vulnerability-scan, build]
+ runs-on: ubuntu-latest
+ name: ci/github/publish
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v2
+ - name: Get Version
+ id: get_version
+ run: |
+ echo "::set-output name=branch::${GITHUB_REF:10}"
+
+ dotnet tool restore
+ version=$(dotnet tool run minver -- --tag-prefix=v)
+ echo "::set-output name=version::${version}"
+ - shell: bash
+ run: |
+ git fetch --prune --unshallow
+ - name: Setup Dotnet
+ uses: actions/setup-dotnet@v1
+ with:
+ dotnet-version: ${{ env.DOTNET_VERSION }}
+ - name: Dotnet Pack
+ shell: bash
+ run: |
+ dotnet pack /p:Version=${{ steps.get_version.outputs.version }} --configuration=Release --output=./packages \
+
+ - name: Publish Artifacts
+ uses: actions/upload-artifact@v1
+ with:
+ path: packages
+ name: nuget-packages
+ - name: Dotnet Push to Nuget.org
+ shell: bash
+ if: contains(steps.get_version.outputs.branch, 'v')
+ run: |
+ dotnet tool restore
+ find . -name "*.nupkg" | xargs -n1 dotnet nuget push --api-key=${{ secrets.NUGET_API_KEY }} --source https://api.nuget.org/v3/index.json
+
\ No newline at end of file
diff --git a/.idea/.idea.SandboxFunctions/.idea/.name b/.idea/.idea.SandboxFunctions/.idea/.name
new file mode 100644
index 0000000..3d7a599
--- /dev/null
+++ b/.idea/.idea.SandboxFunctions/.idea/.name
@@ -0,0 +1 @@
+SandboxFunctions
\ No newline at end of file
diff --git a/.idea/.idea.SandboxFunctions/.idea/contentModel.xml b/.idea/.idea.SandboxFunctions/.idea/contentModel.xml
new file mode 100644
index 0000000..2b32b15
--- /dev/null
+++ b/.idea/.idea.SandboxFunctions/.idea/contentModel.xml
@@ -0,0 +1,50 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/.idea.SandboxFunctions/.idea/encodings.xml b/.idea/.idea.SandboxFunctions/.idea/encodings.xml
new file mode 100644
index 0000000..df87cf9
--- /dev/null
+++ b/.idea/.idea.SandboxFunctions/.idea/encodings.xml
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/.idea/.idea.SandboxFunctions/.idea/indexLayout.xml b/.idea/.idea.SandboxFunctions/.idea/indexLayout.xml
new file mode 100644
index 0000000..27ba142
--- /dev/null
+++ b/.idea/.idea.SandboxFunctions/.idea/indexLayout.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/.idea.SandboxFunctions/.idea/modules.xml b/.idea/.idea.SandboxFunctions/.idea/modules.xml
new file mode 100644
index 0000000..00d3818
--- /dev/null
+++ b/.idea/.idea.SandboxFunctions/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/.idea.SandboxFunctions/.idea/projectSettingsUpdater.xml b/.idea/.idea.SandboxFunctions/.idea/projectSettingsUpdater.xml
new file mode 100644
index 0000000..4bb9f4d
--- /dev/null
+++ b/.idea/.idea.SandboxFunctions/.idea/projectSettingsUpdater.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/.idea.SandboxFunctions/.idea/riderModule.iml b/.idea/.idea.SandboxFunctions/.idea/riderModule.iml
new file mode 100644
index 0000000..fbc44a8
--- /dev/null
+++ b/.idea/.idea.SandboxFunctions/.idea/riderModule.iml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/.idea.SandboxFunctions/.idea/vcs.xml b/.idea/.idea.SandboxFunctions/.idea/vcs.xml
new file mode 100644
index 0000000..94a25f7
--- /dev/null
+++ b/.idea/.idea.SandboxFunctions/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/.idea.SandboxFunctions/.idea/workspace.xml b/.idea/.idea.SandboxFunctions/.idea/workspace.xml
new file mode 100644
index 0000000..d31c003
--- /dev/null
+++ b/.idea/.idea.SandboxFunctions/.idea/workspace.xml
@@ -0,0 +1,112 @@
+
+
+
+ CustomerFunctions/CustomerFunctions.csproj
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1609631825791
+
+
+ 1609631825791
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ file://$PROJECT_DIR$/AcceptanceTests/CustomerAcceptanceTests.cs
+ 92
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/AcceptanceTests/AcceptanceTests.csproj b/AcceptanceTests/AcceptanceTests.csproj
new file mode 100644
index 0000000..b915bc5
--- /dev/null
+++ b/AcceptanceTests/AcceptanceTests.csproj
@@ -0,0 +1,36 @@
+
+
+
+ netcoreapp3.1
+
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Always
+
+
+
+ Always
+
+
+
+
diff --git a/AcceptanceTests/CustomerAcceptanceTests.cs b/AcceptanceTests/CustomerAcceptanceTests.cs
new file mode 100644
index 0000000..ea0feb1
--- /dev/null
+++ b/AcceptanceTests/CustomerAcceptanceTests.cs
@@ -0,0 +1,27 @@
+using Microsoft.Extensions.Primitives;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using System.Collections.Generic;
+using System.Threading;
+using System.Threading.Tasks;
+using AzureFunctions.AcceptanceTest.Runner;
+using CustomerFunctions;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.Azure.WebJobs;
+
+namespace AcceptanceTests
+{
+ [TestClass]
+ public class CustomerAcceptanceTests : BaseFunctionAcceptanceTests
+ {
+ [TestMethod]
+ public async Task WhenCallCustomerGet_ShouldReturn201()
+ {
+ var query = new Dictionary();
+ var body = "{\"name\":\"yamada\"}";
+ var req = HttpRequestSetup(query, body, "get");
+ var result = await AzureFunctionInvoker.Invoke((request) => CustomerFunction.Run(request, logger), req);
+ var resultObject = (OkObjectResult) result;
+ Assert.AreEqual("Hello, yamada. This HTTP triggered function executed successfully.", resultObject.Value);
+ }
+ }
+}
\ No newline at end of file
diff --git a/AcceptanceTests/appsettings.Debug.json b/AcceptanceTests/appsettings.Debug.json
new file mode 100644
index 0000000..73e9de5
--- /dev/null
+++ b/AcceptanceTests/appsettings.Debug.json
@@ -0,0 +1,10 @@
+{
+ "Logging": {
+ "LogLevel": {
+ "Default": "Debug",
+ "System": "Information",
+ "Microsoft": "Information"
+ }
+ },
+ "environment": "debug"
+}
\ No newline at end of file
diff --git a/AcceptanceTests/appsettings.json b/AcceptanceTests/appsettings.json
new file mode 100644
index 0000000..8f7d855
--- /dev/null
+++ b/AcceptanceTests/appsettings.json
@@ -0,0 +1,10 @@
+{
+ "Logging": {
+ "LogLevel": {
+ "Default": "Debug",
+ "System": "Information",
+ "Microsoft": "Information"
+ }
+ },
+ "environment": "localhost"
+}
\ No newline at end of file
diff --git a/AzureFunctions.AcceptanceTest.Runner/AzureFunctionInvoker.cs b/AzureFunctions.AcceptanceTest.Runner/AzureFunctionInvoker.cs
new file mode 100644
index 0000000..b511c3a
--- /dev/null
+++ b/AzureFunctions.AcceptanceTest.Runner/AzureFunctionInvoker.cs
@@ -0,0 +1,82 @@
+using System;
+using System.IO;
+using System.Linq.Expressions;
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.Extensions.Configuration;
+using RestSharp;
+
+namespace AzureFunctions.AcceptanceTest.Runner
+{
+ public static class AzureFunctionInvoker
+ {
+ public static async Task Invoke(Expression>> func,
+ HttpRequest data)
+ {
+ var builder = new ConfigurationBuilder()
+ .SetBasePath(Directory.GetCurrentDirectory())
+ .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true);
+
+ var config = builder.Build();
+ var stage = config["environment"];
+ switch (stage)
+ {
+ case "remote":
+ {
+ var url = config["url"];
+ return await RestCall(data, url);
+ }
+ case "localhost":
+ {
+ throw new NotImplementedException("Need to implement this feature...");
+ }
+ case "debug":
+ {
+ return await func.Compile().Invoke(data);
+ }
+ default:
+ {
+ throw new ArgumentException("Please set stage variable to run acceptance tests.");
+ }
+ }
+ }
+
+ private static async Task RestCall(HttpRequest data, string url)
+ {
+ if (string.IsNullOrEmpty(url))
+ {
+ throw new ApplicationException("Remote call exception url not defined");
+ }
+
+ var client = new RestClient(url);
+ var request = new RestRequest($"customer", FromString(data.Method));
+ StreamReader reader = new StreamReader(data.Body);
+ string text = await reader.ReadToEndAsync();
+ request.AddJsonBody(text);
+ var result = await client.ExecuteAsync(request);
+ return new ActionResult