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/deploy-nuget.yaml b/.github/workflows/deploy-nuget.yaml index 87d64cf..9c9f329 100644 --- a/.github/workflows/deploy-nuget.yaml +++ b/.github/workflows/deploy-nuget.yaml @@ -38,5 +38,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 diff --git a/.github/workflows/sonarqube.yaml b/.github/workflows/sonarqube.yaml new file mode 100644 index 0000000..8e49654 --- /dev/null +++ b/.github/workflows/sonarqube.yaml @@ -0,0 +1,23 @@ +--- +name: Run SonarQube Analysis + +on: + push: + branches: + - main + + paths-ignore: + - "**.md" + - ".vscode/**" + +concurrency: + group: sonarqube-analysis + +jobs: + test: + uses: ./.github/workflows/tests-base.yaml + with: + sonarqube: true + sonarqube_host: ${{ vars.SONARQUBE_HOST }} + secrets: + SONARQUBE_TOKEN: ${{ secrets.SONARQUBE_TOKEN }} diff --git a/.github/workflows/tests-base.yaml b/.github/workflows/tests-base.yaml index 27b7efb..c97dd3e 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" @@ -15,9 +18,11 @@ on: required: false default: false - secrets: - SONARQUBE_HOST: + sonarqube_host: + type: string required: false + + secrets: SONARQUBE_TOKEN: required: false @@ -28,9 +33,6 @@ 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: @@ -42,7 +44,6 @@ jobs: if: ${{ !inputs.sonarqube }} - name: Run tests - if: ${{ !inputs.sonarqube }} run: dotnet test ############################### @@ -69,7 +70,7 @@ jobs: run: | dotnet tool run dotnet-sonarscanner begin -k:"$PROJECT_KEY" \ -d:sonar.login="$SONARQUBE_TOKEN" \ - -d:sonar.host.url="$SONARQUBE_HOST" \ + -d:sonar.host.url="${{ inputs.sonarqube_host }}" \ -d:sonar.cs.vscoveragexml.reportsPaths=coverage.xml dotnet build --no-incremental 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 ITransitionStart AddWorkflowDefinition 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 WorkflowDefinitionWrapper(WorkflowDefinitionBuilder 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 void Test() 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 void Test() 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 void IdGenerationTest() .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 void UnknownWorkflowReferenceThrows() .To(PhoneState.Ringing); var sp = sc.BuildServiceProvider(); - var workflowFactory = sp.GetRequiredService>(); + var workflowFactory = sp.GetRequiredWorkflowFactory(); Assert.Throws(() => workflowFactory.CreateWorkflow("unknown")); }