From 3dd57f5c92eed871c56e875c3b1870a642520bd8 Mon Sep 17 00:00:00 2001 From: "Shkar T. Noori" Date: Thu, 21 Jul 2022 12:54:45 +0000 Subject: [PATCH 1/4] Enable sonarqube analysis --- .config/dotnet-tools.json | 4 +-- .github/workflows/sonarqube.yaml | 51 ++++++++++++++++++++++++++++++ .github/workflows/tests-base.yaml | 52 ++----------------------------- 3 files changed, 55 insertions(+), 52 deletions(-) create mode 100644 .github/workflows/sonarqube.yaml diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json index 49bc7f3..b21c6eb 100644 --- a/.config/dotnet-tools.json +++ b/.config/dotnet-tools.json @@ -3,7 +3,7 @@ "isRoot": true, "tools": { "dotnet-sonarscanner": { - "version": "5.6.0", + "version": "5.7.2", "commands": [ "dotnet-sonarscanner" ] @@ -15,4 +15,4 @@ ] } } -} \ No newline at end of file +} diff --git a/.github/workflows/sonarqube.yaml b/.github/workflows/sonarqube.yaml new file mode 100644 index 0000000..2508672 --- /dev/null +++ b/.github/workflows/sonarqube.yaml @@ -0,0 +1,51 @@ +name: Run SonarQube Analysis + +on: + push: + branches: + - main + + paths-ignore: + - "**.md" + - ".vscode/**" + +concurrency: + group: sonarqube-analysis + +jobs: + run-tests: + name: Run SonarQube Analysis + timeout-minutes: 10 + runs-on: ubuntu-latest + + env: + PROJECT_KEY: ditkrg_DIT.Workflower_AYF14rjSb80e2b0bns3t + SONARQUBE_HOST: ${{ secrets.SONARQUBE_HOST }} + SONARQUBE_TOKEN: ${{ secrets.SONARQUBE_TOKEN }} + ASPNETCORE_ENVIRONMENT: Testing + + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis + + - name: Set up JDK 11 + uses: actions/setup-java@v3 + with: + distribution: "zulu" + java-version: "11" + + - name: Restore tools + run: dotnet tool restore + + - name: Run Tests (SonarQube) + run: | + dotnet tool run dotnet-sonarscanner begin -k:"$PROJECT_KEY" \ + -d:sonar.login="$SONARQUBE_TOKEN" \ + -d:sonar.host.url="$SONARQUBE_HOST" \ + -d:sonar.cs.vscoveragexml.reportsPaths=coverage.xml + + dotnet build --no-incremental + dotnet dotnet-coverage collect "dotnet test" -f xml -o "coverage.xml" + + dotnet tool run dotnet-sonarscanner end -d:sonar.login="$SONARQUBE_TOKEN" diff --git a/.github/workflows/tests-base.yaml b/.github/workflows/tests-base.yaml index f5053c2..b42a2bf 100644 --- a/.github/workflows/tests-base.yaml +++ b/.github/workflows/tests-base.yaml @@ -9,17 +9,6 @@ on: - "!.github/workflows/tests-base.yaml" workflow_call: - inputs: - sonarqube: - type: boolean - required: false - default: fals - - secrets: - SONARQUBE_HOST: - required: false - SONARQUBE_TOKEN: - required: false jobs: run-tests: @@ -28,51 +17,14 @@ jobs: runs-on: ubuntu-latest env: - PROJECT_KEY: ditkrg_DIT.Workflower_AYF14rjSb80e2b0bns3t - SONARQUBE_HOST: ${{ secrets.SONARQUBE_HOST }} - SONARQUBE_TOKEN: ${{ secrets.SONARQUBE_TOKEN }} ASPNETCORE_ENVIRONMENT: Testing steps: + - uses: actions/checkout@v3 + - uses: actions/setup-dotnet@v2 with: dotnet-version: "6.0.x" - - uses: actions/checkout@v3 - if: ${{ !inputs.sonarqube }} - - name: Run tests - if: ${{ !inputs.sonarqube }} run: dotnet test - - ############################### - ########## SONARQUBE ########## - ############################### - - name: Set up JDK 11 - uses: actions/setup-java@v3 - if: ${{ inputs.sonarqube }} - with: - distribution: "zulu" - java-version: "11" - - - uses: actions/checkout@v3 - if: ${{ inputs.sonarqube }} - with: - fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis - - - name: Restore tools - if: ${{ inputs.sonarqube }} - run: dotnet tool restore - - - name: Run tests (SonarQube) - if: ${{ inputs.sonarqube }} - run: | - dotnet tool run dotnet-sonarscanner begin -k:"$PROJECT_KEY" \ - -d:sonar.login="$SONARQUBE_TOKEN" \ - -d:sonar.host.url="$SONARQUBE_HOST" \ - -d:sonar.cs.vscoveragexml.reportsPaths=coverage.xml - - dotnet build --no-incremental - dotnet dotnet-coverage collect "dotnet test" -f xml -o "coverage.xml" - - dotnet tool run dotnet-sonarscanner end -d:sonar.login="$SONARQUBE_TOKEN" From 17ea5053456b702c59a7ff26ebfc4439aabcd89f Mon Sep 17 00:00:00 2001 From: "Shkar T. Noori" Date: Thu, 21 Jul 2022 12:55:38 +0000 Subject: [PATCH 2/4] Ignore tests on main branch --- .github/workflows/tests-base.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/tests-base.yaml b/.github/workflows/tests-base.yaml index b42a2bf..cfd3a84 100644 --- a/.github/workflows/tests-base.yaml +++ b/.github/workflows/tests-base.yaml @@ -2,6 +2,9 @@ name: Run Tests on: push: + branches-ignore: + - main + paths-ignore: - "**.md" From c0691416a883f1c92a2d82776499f97a3d889efa Mon Sep 17 00:00:00 2001 From: "Shkar T. Noori" Date: Thu, 21 Jul 2022 13:08:31 +0000 Subject: [PATCH 3/4] Rename nuget secret --- .github/workflows/deploy-nuget.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/deploy-nuget.yaml b/.github/workflows/deploy-nuget.yaml index 0958162..77ec112 100644 --- a/.github/workflows/deploy-nuget.yaml +++ b/.github/workflows/deploy-nuget.yaml @@ -37,5 +37,5 @@ jobs: run: |- dotnet nuget push "packages/*.nupkg" \ --skip-duplicate \ - --api-key ${{ secrets.NUGET__API_KEY }} \ + --api-key ${{ secrets.NUGET_API_KEY }} \ --source https://api.nuget.org/v3/index.json From 86c2f3e9c4504731c330141db2630ab031589a55 Mon Sep 17 00:00:00 2001 From: "Shkar T. Noori" Date: Sun, 24 Jul 2022 08:38:39 +0000 Subject: [PATCH 4/4] Add helper functions to create workflows, access service provider in When clause --- .../Common.cs | 3 ++ .../IServiceCollectionExtensions.cs | 16 ++++----- .../Extensions/IServiceProviderExtensions.cs | 35 +++++++++++++++++++ .../WorkflowDefinitionWrapper.cs | 8 ++++- .../DependencyInjectionTests.cs | 12 ++++--- 5 files changed, 60 insertions(+), 14 deletions(-) create mode 100644 src/DIT.Workflower.DependencyInjection/Common.cs create mode 100644 src/DIT.Workflower.DependencyInjection/Extensions/IServiceProviderExtensions.cs diff --git a/src/DIT.Workflower.DependencyInjection/Common.cs b/src/DIT.Workflower.DependencyInjection/Common.cs new file mode 100644 index 0000000..d2235ac --- /dev/null +++ b/src/DIT.Workflower.DependencyInjection/Common.cs @@ -0,0 +1,3 @@ +namespace DIT.Workflower.DependencyInjection; + +public record DIContextWrapper(TContext Context, IServiceProvider ServiceProvider); diff --git a/src/DIT.Workflower.DependencyInjection/Extensions/IServiceCollectionExtensions.cs b/src/DIT.Workflower.DependencyInjection/Extensions/IServiceCollectionExtensions.cs index 285ba74..269b7c7 100644 --- a/src/DIT.Workflower.DependencyInjection/Extensions/IServiceCollectionExtensions.cs +++ b/src/DIT.Workflower.DependencyInjection/Extensions/IServiceCollectionExtensions.cs @@ -5,7 +5,7 @@ namespace DIT.Workflower.DependencyInjection.Extensions; public static class IServiceCollectionExtensions { - public static ITransitionStart AddWorkflowDefinition(this IServiceCollection services, in int version = 1) + public static ITransitionStart> AddWorkflowDefinition(this IServiceCollection services, in int version = 1) where TState : struct where TCommand : struct { @@ -13,25 +13,25 @@ public static class IServiceCollectionExtensions return AddWorkflowDefinition(services, id, version); } - public static ITransitionStart AddWorkflowDefinition(this IServiceCollection services, in string id) + public static ITransitionStart> AddWorkflowDefinition(this IServiceCollection services, in string id) where TState : struct where TCommand : struct { return AddWorkflowDefinition(services, id, version: 1); } - public static ITransitionStart AddWorkflowDefinition(this IServiceCollection services, string id, int version) + public static ITransitionStart> AddWorkflowDefinition(this IServiceCollection services, string id, int version) where TState : struct where TCommand : struct { - var builder = WorkflowDefinitionBuilder.Create(); + var builder = WorkflowDefinitionBuilder>.Create(); - services.TryAddSingleton, DefaultWorkflowFactory>(); + services.TryAddSingleton>, DefaultWorkflowFactory>>(); - services.AddSingleton, WorkflowDefinitionWrapper>(sp => + services.AddSingleton>, WorkflowDefinitionWrapper>>(sp => { - var definition = (WorkflowDefinitionBuilder)builder; - var wrapper = new WorkflowDefinitionWrapper(definition, id, version); + var definition = (WorkflowDefinitionBuilder>)builder; + var wrapper = new WorkflowDefinitionWrapper>(definition, id, version); return wrapper; }); diff --git a/src/DIT.Workflower.DependencyInjection/Extensions/IServiceProviderExtensions.cs b/src/DIT.Workflower.DependencyInjection/Extensions/IServiceProviderExtensions.cs new file mode 100644 index 0000000..a094cf3 --- /dev/null +++ b/src/DIT.Workflower.DependencyInjection/Extensions/IServiceProviderExtensions.cs @@ -0,0 +1,35 @@ +namespace DIT.Workflower.DependencyInjection.Extensions; + +public static class IServiceProviderExtensions +{ + public static IWorkflowFactory> GetRequiredWorkflowFactory(this IServiceProvider sp) + where TState : struct + where TCommand : struct + { + return sp.GetRequiredService>>(); + } + + public static IWorkflowFactory>? GetWorkflowFactory(this IServiceProvider sp) + where TState : struct + where TCommand : struct + { + return sp.GetService>>(); + } + + public static IWorkflow> CreateWorkflow(this IServiceProvider sp, int version = 1) + where TState : struct + where TCommand : struct + { + var factory = GetRequiredWorkflowFactory(sp); + return factory.CreateWorkflow(version); + } + + public static IWorkflow> CreateWorkflow(this IServiceProvider sp, string id, int version = 1) + where TState : struct + where TCommand : struct + { + var factory = GetRequiredWorkflowFactory(sp); + return factory.CreateWorkflow(id, version); + } + +} diff --git a/src/DIT.Workflower.DependencyInjection/WorkflowDefinitionWrapper.cs b/src/DIT.Workflower.DependencyInjection/WorkflowDefinitionWrapper.cs index 2c70d6d..571d512 100644 --- a/src/DIT.Workflower.DependencyInjection/WorkflowDefinitionWrapper.cs +++ b/src/DIT.Workflower.DependencyInjection/WorkflowDefinitionWrapper.cs @@ -18,7 +18,13 @@ public record WorkflowDefinitionWrapper : WorkflowDe public static string GetDefaultId() { - return $"{typeof(TState).Name}_{typeof(TCommand).Name}_{typeof(TContext).Name}"; + var ctxType = typeof(TContext); + var ctxName = ctxType.Name; + + if (ctxType.IsGenericType) + ctxName = string.Join("+", typeof(TContext).GetGenericArguments().Select(x => x.Name)); + + return $"{typeof(TState).Name}_{typeof(TCommand).Name}_{ctxName}"; } } diff --git a/tests/DIT.Workflower.Tests/DependencyInjection/DependencyInjectionTests.cs b/tests/DIT.Workflower.Tests/DependencyInjection/DependencyInjectionTests.cs index f06cd4b..1b1be3e 100644 --- a/tests/DIT.Workflower.Tests/DependencyInjection/DependencyInjectionTests.cs +++ b/tests/DIT.Workflower.Tests/DependencyInjection/DependencyInjectionTests.cs @@ -40,8 +40,7 @@ public class DependencyInjectionTests var sp = sc.BuildServiceProvider(); - var workflowFactory = sp.GetRequiredService>(); - + var workflowFactory = sp.GetRequiredWorkflowFactory(); var v1 = workflowFactory.CreateWorkflow(id); var v2 = workflowFactory.CreateWorkflow(id, version: 2); @@ -62,6 +61,7 @@ public class DependencyInjectionTests public void IdGenerationTest() { var sc = new ServiceCollection(); + const string expectedId = "PhoneState_PhoneCommand_PhoneCall"; sc.AddWorkflowDefinition(version: 1) .From(PhoneState.Idle) @@ -69,10 +69,12 @@ public class DependencyInjectionTests .To(PhoneState.Ringing); var sp = sc.BuildServiceProvider(); - var workflowFactory = sp.GetRequiredService>(); + var workflowFactory = sp.GetRequiredWorkflowFactory(); var workflow = workflowFactory.CreateWorkflow(); - Assert.Equal("PhoneState_PhoneCommand_PhoneCall", workflow.Id); + Assert.Equal(expectedId, workflow.Id); + Assert.Equal(expectedId, sp.CreateWorkflow().Id); + Assert.Equal(expectedId, sp.CreateWorkflow(expectedId).Id); } [Fact] @@ -86,7 +88,7 @@ public class DependencyInjectionTests .To(PhoneState.Ringing); var sp = sc.BuildServiceProvider(); - var workflowFactory = sp.GetRequiredService>(); + var workflowFactory = sp.GetRequiredWorkflowFactory(); Assert.Throws(() => workflowFactory.CreateWorkflow("unknown")); }