diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml index 481d3e16..a8f154e6 100644 --- a/.github/workflows/build-and-test.yml +++ b/.github/workflows/build-and-test.yml @@ -8,22 +8,24 @@ on: jobs: build: - name: "Build" + name: Build runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Cache - uses: actions/cache@v4 - with: + uses: actions/cache@v5 + with: path: ~/.nuget/packages - key: ${{ runner.os }}-nuget-${{ hashFiles('**/packages.lock.json') }} - restore-keys: | + key: ${{ runner.os }}-nuget-${{ hashFiles('**/packages.lock.json') }} + restore-keys: | ${{ runner.os }}-nuget- - name: Setup .NET - uses: actions/setup-dotnet@v4 + uses: actions/setup-dotnet@v5 + with: + global-json-file: global.json - name: Restore dependencies run: dotnet restore @@ -32,24 +34,35 @@ jobs: run: dotnet build --no-restore --configuration Release - name: Test - run: dotnet test --no-build --no-restore --configuration Release -- --report-xunit-trx + run: | + dotnet test --no-build --no-restore --configuration Release \ + --report-xunit-trx \ + --coverage \ + --coverage-output-format cobertura \ + --coverage-output coverage.cobertura.xml \ + --no-progress + + - name: Publish Test Results + if: always() + run: | + dotnet tool install --global dotnet-reportgenerator-globaltool + + reportgenerator \ + -reports:"$(pwd)/**/coverage.cobertura.xml" \ + -targetdir:"$(pwd)" \ + -filefilters:"+*;-**/*.g.cs" \ + -reporttypes:MarkdownSummaryGithub + + cat SummaryGithub.md >> $GITHUB_STEP_SUMMARY - name: Publish + if: github.event_name != 'pull_request' run: dotnet publish src/WebApi/WebApi.csproj --no-build --no-restore --configuration Release --output ./publish - name: Upload Artifact - uses: actions/upload-artifact@v4 + if: github.event_name != 'pull_request' + uses: actions/upload-artifact@v6 with: name: published-files path: ./publish - - name: Test Report - uses: test-summary/action@v2 - if: success() || failure() - with: - paths: ./**/test-result.xml - output: test-summary.md - - name: Output job summary - if: success() || failure() - run: | - cat test-summary.md >> $GITHUB_STEP_SUMMARY diff --git a/Directory.Packages.props b/Directory.Packages.props index 1434f4de..f82a9717 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -5,28 +5,19 @@ - - - + + + - - - + + - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - - @@ -37,15 +28,11 @@ runtime; build; native; contentfiles; analyzers; buildtransitive - - - - + - @@ -53,11 +40,11 @@ - + - - + + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/SSW.CleanArchitecture.slnx b/SSW.CleanArchitecture.slnx index abd74f97..cfc770fd 100644 --- a/SSW.CleanArchitecture.slnx +++ b/SSW.CleanArchitecture.slnx @@ -1,4 +1,4 @@ - + @@ -16,10 +16,10 @@ - + - - + + \ No newline at end of file diff --git a/global.json b/global.json index d46d21e5..df32a2e3 100644 --- a/global.json +++ b/global.json @@ -3,5 +3,8 @@ "version": "10.0.100", "rollForward": "latestFeature", "allowPrerelease": false + }, + "test": { + "runner": "Microsoft.Testing.Platform" } } diff --git a/src/Application/Application.csproj b/src/Application/Application.csproj index 923ccc2c..635bead6 100644 --- a/src/Application/Application.csproj +++ b/src/Application/Application.csproj @@ -13,9 +13,6 @@ - - - diff --git a/src/Infrastructure/DependencyInjection.cs b/src/Infrastructure/DependencyInjection.cs index 5674435c..52431961 100644 --- a/src/Infrastructure/DependencyInjection.cs +++ b/src/Infrastructure/DependencyInjection.cs @@ -26,7 +26,7 @@ public static void AddInfrastructure(this IHostApplicationBuilder builder) var services = builder.Services; - services.AddScoped(sp => sp.GetRequiredService()); + services.AddScoped(); services.AddScoped(); services.AddScoped(); diff --git a/src/Infrastructure/Infrastructure.csproj b/src/Infrastructure/Infrastructure.csproj index ba7f8564..81cea32b 100644 --- a/src/Infrastructure/Infrastructure.csproj +++ b/src/Infrastructure/Infrastructure.csproj @@ -1,4 +1,4 @@ - + SSW.CleanArchitecture.Infrastructure SSW.CleanArchitecture.Infrastructure @@ -14,9 +14,6 @@ - - - diff --git a/src/Infrastructure/ServiceDefaults/Extensions.cs b/src/Infrastructure/ServiceDefaults/Extensions.cs index d660e7f8..f0023bd9 100644 --- a/src/Infrastructure/ServiceDefaults/Extensions.cs +++ b/src/Infrastructure/ServiceDefaults/Extensions.cs @@ -2,18 +2,14 @@ using Microsoft.AspNetCore.Diagnostics.HealthChecks; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Diagnostics.HealthChecks; +using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; using OpenTelemetry; using OpenTelemetry.Metrics; using OpenTelemetry.Trace; -// TODO: Investigate and fix IDE0055 warnings on Unix (runners) -#pragma warning disable IDE0055 +namespace SSW.CleanArchitecture.Infrastructure.ServiceDefaults; -// ReSharper disable once CheckNamespace -#pragma warning disable IDE0130 -namespace Microsoft.Extensions.Hosting; -#pragma warning restore IDE0130 // Adds common .NET Aspire services: service discovery, resilience, health checks, and OpenTelemetry. // This project should be referenced by each service project in your solution. // To learn more about using this project, see https://aka.ms/dotnet/aspire/service-defaults @@ -120,4 +116,4 @@ public static WebApplication MapDefaultEndpoints(this WebApplication app) return app; } } -#pragma warning restore IDE0055 + diff --git a/src/WebApi/HealthChecks/WebApplicationHealthCheckExtensions.cs b/src/WebApi/HealthChecks/WebApplicationHealthCheckExtensions.cs index 2726e118..f52910ab 100644 --- a/src/WebApi/HealthChecks/WebApplicationHealthCheckExtensions.cs +++ b/src/WebApi/HealthChecks/WebApplicationHealthCheckExtensions.cs @@ -33,28 +33,19 @@ public static void AddHealthChecks(this IServiceCollection services, IConfigurat // Check 1: Check the SQL Server Connectivity (no EF, no DBContext, hardly anything to go wrong) .AddSqlServer( name: "SQL Server", - connectionString: config["ConnectionStrings:DefaultConnection"]!, + connectionString: config.GetConnectionString("CleanArchitecture")!, healthQuery: $"-- SqlServerHealthCheck{Environment.NewLine}SELECT 123;", failureStatus: HealthStatus.Unhealthy, tags: ["db", "sql", "sqlserver"]) // Check 2: Check the Entity Framework DbContext (requires the DbContext Options, DI, Interceptors, Configurations, etc. to all be correct), and - // then run a sample query to test important data - // Note: Add TagWith("HealthCheck") to show up in SQL Profiling tools (usually as the opening comment) so that you know that the constant DB Queries are - // for the health check of the current application and not something strange/unidentified. + // then run a query to test pending migrations .AddEntityFrameworkDbContextCheck( name: "Entity Framework DbContext", tags: ["db", "dbContext", "sql"], - testQuery: async (ctx, ct) => - { - // TODO: Replace the custom test query below with something appropriate for your project that is always expected to be valid - _ = await ctx - .Heroes - // allows you to understand why you might see constant db queries in sql profile - .TagWith("HealthCheck") - .FirstOrDefaultAsync(ct); - - return new DbHealthCheckResult("Database Context is healthy"); - }); + testQuery: async (ctx, ct) => (await ctx.Database.GetPendingMigrationsAsync(ct)).Any() + ? new DbHealthCheckResult("There are pending database migrations. Please apply them first.", exception: null) + : new DbHealthCheckResult("All migrations are applied") + ); } } \ No newline at end of file diff --git a/src/WebApi/Program.cs b/src/WebApi/Program.cs index 44e563e4..4d0801e0 100644 --- a/src/WebApi/Program.cs +++ b/src/WebApi/Program.cs @@ -1,5 +1,6 @@ using SSW.CleanArchitecture.Application; using SSW.CleanArchitecture.Infrastructure; +using SSW.CleanArchitecture.Infrastructure.ServiceDefaults; using SSW.CleanArchitecture.WebApi; using SSW.CleanArchitecture.WebApi.Endpoints; using SSW.CleanArchitecture.WebApi.Extensions; @@ -31,7 +32,6 @@ app.MapCustomScalarApiReference(); app.UseHealthChecks(); app.UseHttpsRedirection(); -app.UseStaticFiles(); app.MapHeroEndpoints(); app.MapTeamEndpoints(); diff --git a/src/WebApi/WebApi.csproj b/src/WebApi/WebApi.csproj index 5b2196c9..3aefd414 100644 --- a/src/WebApi/WebApi.csproj +++ b/src/WebApi/WebApi.csproj @@ -15,7 +15,6 @@ - diff --git a/src/WebApi/appsettings.Development.json b/src/WebApi/appsettings.Development.json index 71ed7063..0c208ae9 100644 --- a/src/WebApi/appsettings.Development.json +++ b/src/WebApi/appsettings.Development.json @@ -4,8 +4,5 @@ "Default": "Information", "Microsoft.AspNetCore": "Warning" } - }, - "ConnectionStrings": { - "DefaultConnection": "Server=localhost,1500;Initial Catalog=CleanArchitecture;Persist Security Info=False;User ID=sa;Password=yourStrong(!)Password;MultipleActiveResultSets=True;TrustServerCertificate=True;Connection Timeout=30;" } } diff --git a/tests/Architecture.Tests/Architecture.Tests.csproj b/tests/Architecture.Tests/Architecture.Tests.csproj index 13cda3a5..af84f52d 100644 --- a/tests/Architecture.Tests/Architecture.Tests.csproj +++ b/tests/Architecture.Tests/Architecture.Tests.csproj @@ -1,4 +1,4 @@ - + SSW.CleanArchitecture.Architecture.UnitTests SSW.CleanArchitecture.Architecture.UnitTests @@ -9,7 +9,8 @@ - + + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/tests/Domain.UnitTests/Domain.UnitTests.csproj b/tests/Domain.UnitTests/Domain.UnitTests.csproj index 1bb74560..0f0a2de8 100644 --- a/tests/Domain.UnitTests/Domain.UnitTests.csproj +++ b/tests/Domain.UnitTests/Domain.UnitTests.csproj @@ -1,17 +1,15 @@ - + SSW.CleanArchitecture.Domain.UnitTests SSW.CleanArchitecture.Domain.UnitTests false - true - true - Exe - + + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/tests/WebApi.IntegrationTests/WebApi.IntegrationTests.csproj b/tests/WebApi.IntegrationTests/WebApi.IntegrationTests.csproj index 6df17387..9ccffabd 100644 --- a/tests/WebApi.IntegrationTests/WebApi.IntegrationTests.csproj +++ b/tests/WebApi.IntegrationTests/WebApi.IntegrationTests.csproj @@ -1,22 +1,21 @@ - - + + SSW.CleanArchitecture.WebApi.IntegrationTests + SSW.CleanArchitecture.WebApi.IntegrationTests false - true - - - + + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/tools/AppHost/AppHost.csproj b/tools/AppHost/AppHost.csproj index 44b41331..55575adb 100644 --- a/tools/AppHost/AppHost.csproj +++ b/tools/AppHost/AppHost.csproj @@ -1,4 +1,4 @@ - + Exe diff --git a/tools/MigrationService/MigrationService.csproj b/tools/MigrationService/MigrationService.csproj index a8e0fc26..e3be1651 100644 --- a/tools/MigrationService/MigrationService.csproj +++ b/tools/MigrationService/MigrationService.csproj @@ -3,7 +3,6 @@ - diff --git a/tools/MigrationService/Program.cs b/tools/MigrationService/Program.cs index 8da168cf..753e13ae 100644 --- a/tools/MigrationService/Program.cs +++ b/tools/MigrationService/Program.cs @@ -3,6 +3,7 @@ using SSW.CleanArchitecture.Application.Common.Interfaces; using SSW.CleanArchitecture.Infrastructure.Persistence; using SSW.CleanArchitecture.Infrastructure.Persistence.Interceptors; +using SSW.CleanArchitecture.Infrastructure.ServiceDefaults; var builder = Host.CreateApplicationBuilder(args);