Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 38 additions & 53 deletions .github/workflows/pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ on:
jobs:
build:
name: 🛠️ Build
runs-on: ubuntu-22.04
runs-on: ubuntu-24.04
strategy:
matrix:
configuration: [Debug, Release]
Expand Down Expand Up @@ -62,7 +62,7 @@ jobs:

pack:
name: 📦 Pack
runs-on: ubuntu-22.04
runs-on: ubuntu-24.04
strategy:
matrix:
configuration: [Debug, Release]
Expand All @@ -80,10 +80,16 @@ jobs:
uploadPackedArtifact: true
version: ${{ needs.build.outputs.version }}

sonarcloud:
name: 🔬 Code Quality Analysis
test:
name: 🧪 Test
needs: [build]
runs-on: ubuntu-22.04
strategy:
fail-fast: false
matrix:
os: [ubuntu-24.04, windows-2022]
configuration: [Debug, Release]
runs-on: ${{ matrix.os }}
timeout-minutes: 15
steps:
- name: Checkout
uses: codebeltnet/git-checkout@v1
Expand All @@ -93,64 +99,43 @@ jobs:
with:
includePreview: true

- name: Install .NET Tool - Sonar Scanner
uses: codebeltnet/dotnet-tool-install-sonarscanner@v1

- name: Restore Dependencies
uses: codebeltnet/dotnet-restore@v2

- name: Run SonarCloud Analysis
uses: codebeltnet/sonarcloud-scan@v1
with:
token: ${{ secrets.SONAR_TOKEN }}
organization: geekle
projectKey: bootstrapper
version: ${{ needs.build.outputs.version }}
- name: Install .NET Tool - Report Generator
uses: codebeltnet/dotnet-tool-install-reportgenerator@v1

- name: Build
uses: codebeltnet/dotnet-build@v2
- name: Test with ${{ matrix.configuration }} build
uses: codebeltnet/dotnet-test@v3
with:
configuration: ${{ matrix.configuration }}
buildSwitches: -p:SkipSignAssembly=true
uploadBuildArtifact: false

- name: Finalize SonarCloud Analysis
uses: codebeltnet/sonarcloud-scan-finalize@v1
with:
token: ${{ secrets.SONAR_TOKEN }}
sonarcloud:
name: call-sonarcloud
needs: [build,test]
uses: codebeltnet/jobs-sonarcloud/.github/workflows/default.yml@v1
with:
organization: geekle
projectKey: bootstrapper
version: ${{ needs.build.outputs.version }}
secrets: inherit

codecov:
name: call-codecov
needs: [build,test]
uses: codebeltnet/jobs-codecov/.github/workflows/default.yml@v1
with:
repository: codebeltnet/bootstrapper
secrets: inherit

codeql:
name: 🛡️ Security Analysis
needs: [build]
runs-on: ubuntu-22.04
steps:
- name: Checkout
uses: codebeltnet/git-checkout@v1

- name: Install .NET
uses: codebeltnet/install-dotnet@v1
with:
includePreview: true

- name: Restore Dependencies
uses: codebeltnet/dotnet-restore@v2

- name: Prepare CodeQL SAST Analysis
uses: codebeltnet/codeql-scan@v1

- name: Build
uses: codebeltnet/dotnet-build@v2
with:
buildSwitches: -p:SkipSignAssembly=true
uploadBuildArtifact: false

- name: Finalize CodeQL SAST Analysis
uses: codebeltnet/codeql-scan-finalize@v1
name: call-codeql
needs: [build,test]
uses: codebeltnet/jobs-codeql/.github/workflows/default.yml@v1

deploy:
if: github.event_name != 'pull_request'
name: 🚀 Deploy v${{ needs.build.outputs.version }}
runs-on: ubuntu-22.04
needs: [build,pack,sonarcloud,codeql]
runs-on: ubuntu-24.04
needs: [build, pack, test, sonarcloud, codecov, codeql]
environment: Production
steps:
- uses: codebeltnet/nuget-push@v1
Expand Down
12 changes: 11 additions & 1 deletion .nuget/Codebelt.Bootstrapper.Console/PackageReleaseNotes.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,14 @@
Version 3.0.1
Version 4.0.0
Availability: .NET 9 and .NET 8

# ALM
- CHANGED Dependencies to latest and greatest with respect to TFMs

# Breaking Changes
- CHANGED UseBootstrapperProgram method on the HostApplicationBuilderExtensions class in the Codebelt.Bootstrapper.Console namespace to extend IHostApplicationBuilder instead of HostApplicationBuilder
- CHANGED UseMinimalConsoleProgram method on the HostApplicationBuilderExtensions class in the Codebelt.Bootstrapper.Console namespace to extend IHostApplicationBuilder instead of HostApplicationBuilder

Version 3.0.1
Availability: .NET 9 and .NET 8

# ALM
Expand Down
8 changes: 7 additions & 1 deletion .nuget/Codebelt.Bootstrapper.Web/PackageReleaseNotes.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
Version 3.0.1
Version 4.0.0
Availability: .NET 9 and .NET 8

# ALM
- CHANGED Dependencies to latest and greatest with respect to TFMs

Version 3.0.1
Availability: .NET 9 and .NET 8

# ALM
Expand Down
8 changes: 7 additions & 1 deletion .nuget/Codebelt.Bootstrapper.Worker/PackageReleaseNotes.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
Version 3.0.1
Version 4.0.0
Availability: .NET 9 and .NET 8

# ALM
- CHANGED Dependencies to latest and greatest with respect to TFMs

Version 3.0.1
Availability: .NET 9 and .NET 8

# ALM
Expand Down
19 changes: 18 additions & 1 deletion .nuget/Codebelt.Bootstrapper/PackageReleaseNotes.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,21 @@
Version 3.0.1
Version 4.0.0
Availability: .NET 9 and .NET 8

# ALM
- CHANGED Dependencies to latest and greatest with respect to TFMs

# Breaking Changes
- REMOVED HostedServiceExtensions class in the Codebelt.Bootstrapper namespace (WaitForApplicationStartedAnnouncementAsync extension method)
- CHANGED BootstrapperLifetime class in the Codebelt.Bootstrapper namespace to implement IHostLifetimeEvents (hereby removing static equivalents)
- CHANGED UseBootstrapperStartup method on the HostApplicationBuilderExtensions class in the Codebelt.Bootstrapper namespace to extend IHostApplicationBuilder instead of HostApplicationBuilder

# New Features
- ADDED IHostLifetimeEvents interface in the Codebelt.Bootstrapper namespace that provides a convenient way to be notified of host lifetime events

# Bug Fixes
- FIXED BootstrapperLifetime class in the Codebelt.Bootstrapper namespace to disregard SuppressStatusMessages and always assign callbacks to members of IHostLifetimeEvents

Version 3.0.1
Availability: .NET 9 and .NET 8

# ALM
Expand Down
23 changes: 23 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,29 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),

For more details, please refer to `PackageReleaseNotes.txt` on a per assembly basis in the `.nuget` folder.

## [4.0.0] - TBD

This major release revisits and refines some of the earlier design decisions to offer a more consistent and flexible API. It also brings forward improvements to reliability and maintainability.

### Added

- IHostLifetimeEvents interface in the Codebelt.Bootstrapper namespace that provides a convenient way to be notified of host lifetime events

### Changed

- BootstrapperLifetime class in the Codebelt.Bootstrapper namespace to implement IHostLifetimeEvents and hereby removing static equivalents (breaking change)
- UseBootstrapperStartup method on the HostApplicationBuilderExtensions class in the Codebelt.Bootstrapper namespace to extend IHostApplicationBuilder instead of HostApplicationBuilder (breaking change)
- UseBootstrapperProgram method on the HostApplicationBuilderExtensions class in the Codebelt.Bootstrapper.Console namespace to extend IHostApplicationBuilder instead of HostApplicationBuilder (breaking change)
- UseMinimalConsoleProgram method on the HostApplicationBuilderExtensions class in the Codebelt.Bootstrapper.Console namespace to extend IHostApplicationBuilder instead of HostApplicationBuilder (breaking change)

### Removed

- HostedServiceExtensions class in the Codebelt.Bootstrapper namespace (breaking change)

### Fixed

- BootstrapperLifetime class in the Codebelt.Bootstrapper namespace to disregard SuppressStatusMessages and always assign callbacks to members of IHostLifetimeEvents

## [3.0.1] - 2025-01-31

This is a service update that primarily focuses on package dependencies and minor improvements.
Expand Down
23 changes: 23 additions & 0 deletions Codebelt.Bootstrapper.sln
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,14 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Codebelt.Bootstrapper.Minim
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Codebelt.Bootstrapper.MinimalWorker.App", "app\Codebelt.Bootstrapper.MinimalWorker.App\Codebelt.Bootstrapper.MinimalWorker.App.csproj", "{E87D127B-4CD1-4009-962E-EEF70A522C13}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{02EA681E-C7D8-13C7-8484-4AC65E1B71E8}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Codebelt.Bootstrapper.Tests", "test\Codebelt.Bootstrapper.Tests\Codebelt.Bootstrapper.Tests.csproj", "{CC656409-7479-4553-8E9B-0854801E1590}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Codebelt.Bootstrapper.FunctionalTests", "test\Codebelt.Bootstrapper.FunctionalTests\Codebelt.Bootstrapper.FunctionalTests.csproj", "{8970491F-E0BD-489D-AA7E-617A67C2E39F}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Codebelt.Bootstrapper.Console.FunctionalTests", "test\Codebelt.Bootstrapper.Console.FunctionalTests\Codebelt.Bootstrapper.Console.FunctionalTests.csproj", "{585A199C-4675-4A8A-89B7-EFF824377456}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -109,6 +117,18 @@ Global
{E87D127B-4CD1-4009-962E-EEF70A522C13}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E87D127B-4CD1-4009-962E-EEF70A522C13}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E87D127B-4CD1-4009-962E-EEF70A522C13}.Release|Any CPU.Build.0 = Release|Any CPU
{CC656409-7479-4553-8E9B-0854801E1590}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{CC656409-7479-4553-8E9B-0854801E1590}.Debug|Any CPU.Build.0 = Debug|Any CPU
{CC656409-7479-4553-8E9B-0854801E1590}.Release|Any CPU.ActiveCfg = Release|Any CPU
{CC656409-7479-4553-8E9B-0854801E1590}.Release|Any CPU.Build.0 = Release|Any CPU
{8970491F-E0BD-489D-AA7E-617A67C2E39F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8970491F-E0BD-489D-AA7E-617A67C2E39F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8970491F-E0BD-489D-AA7E-617A67C2E39F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8970491F-E0BD-489D-AA7E-617A67C2E39F}.Release|Any CPU.Build.0 = Release|Any CPU
{585A199C-4675-4A8A-89B7-EFF824377456}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{585A199C-4675-4A8A-89B7-EFF824377456}.Debug|Any CPU.Build.0 = Debug|Any CPU
{585A199C-4675-4A8A-89B7-EFF824377456}.Release|Any CPU.ActiveCfg = Release|Any CPU
{585A199C-4675-4A8A-89B7-EFF824377456}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -130,6 +150,9 @@ Global
{3C43A01F-51E7-4166-91D5-E2088E68F4E5} = {28409021-5670-4008-9061-DBAAA0FC4DA6}
{497AD6CD-1E7E-4B4D-ACE5-CDD005A14F96} = {28409021-5670-4008-9061-DBAAA0FC4DA6}
{E87D127B-4CD1-4009-962E-EEF70A522C13} = {28409021-5670-4008-9061-DBAAA0FC4DA6}
{CC656409-7479-4553-8E9B-0854801E1590} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8}
{8970491F-E0BD-489D-AA7E-617A67C2E39F} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8}
{585A199C-4675-4A8A-89B7-EFF824377456} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {72FB037E-3629-4CDB-812E-D577A3D4FD26}
Expand Down
2 changes: 1 addition & 1 deletion Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,6 @@
</ItemGroup>

<ItemGroup Condition="'$(IsTestProject)' == 'true'">
<PackageReference Include="Codebelt.Extensions.Xunit" />
<PackageReference Include="Codebelt.Extensions.Xunit.App" />
</ItemGroup>
</Project>
24 changes: 12 additions & 12 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,26 @@
</PropertyGroup>
<ItemGroup>
<PackageVersion Include="Codebelt.Extensions.Swashbuckle.AspNetCore" Version="9.0.1" />
<PackageVersion Include="Codebelt.Extensions.Xunit" Version="9.0.1" />
<PackageVersion Include="Cuemon.Core" Version="9.0.1" />
<PackageVersion Include="Cuemon.Extensions.Hosting" Version="9.0.1" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.12.0" />
<PackageVersion Include="Codebelt.Extensions.Xunit.App" Version="10.0.0-preview.2" />
<PackageVersion Include="Cuemon.Core" Version="9.0.4" />
<PackageVersion Include="Cuemon.Extensions.Hosting" Version="9.0.4" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.13.0" />
<PackageVersion Include="MinVer" Version="6.0.0" />
<PackageVersion Include="coverlet.collector" Version="6.0.4" />
<PackageVersion Include="coverlet.msbuild" Version="6.0.4" />
<PackageVersion Include="xunit" Version="2.9.3" />
<PackageVersion Include="xunit.runner.visualstudio" Version="3.0.1" />
<PackageVersion Include="xunit.runner.visualstudio" Version="3.0.2" />
</ItemGroup>
<ItemGroup Condition="$(TargetFramework.StartsWith('net9'))">
<PackageVersion Include="Microsoft.AspNetCore.OpenApi" Version="9.0.1" />
<PackageVersion Include="Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation" Version="9.0.1" />
<PackageVersion Include="Microsoft.Extensions.Configuration" Version="9.0.1" />
<PackageVersion Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="9.0.1" />
<PackageVersion Include="Microsoft.Extensions.Hosting" Version="9.0.1" />
<PackageVersion Include="Microsoft.AspNetCore.OpenApi" Version="9.0.4" />
<PackageVersion Include="Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation" Version="9.0.4" />
<PackageVersion Include="Microsoft.Extensions.Configuration" Version="9.0.4" />
<PackageVersion Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="9.0.4" />
<PackageVersion Include="Microsoft.Extensions.Hosting" Version="9.0.4" />
</ItemGroup>
<ItemGroup Condition="$(TargetFramework.StartsWith('net8'))">
<PackageVersion Include="Microsoft.AspNetCore.OpenApi" Version="8.0.12" />
<PackageVersion Include="Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation" Version="8.0.12" />
<PackageVersion Include="Microsoft.AspNetCore.OpenApi" Version="8.0.15" />
<PackageVersion Include="Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation" Version="8.0.15" />
<PackageVersion Include="Microsoft.Extensions.Configuration" Version="8.0.0" />
<PackageVersion Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="8.0.2" />
<PackageVersion Include="Microsoft.Extensions.Hosting" Version="8.0.1" />
Expand Down
13 changes: 10 additions & 3 deletions app/Codebelt.Bootstrapper.Console.App/Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,21 @@ public override void ConfigureServices(IServiceCollection services)
public override void ConfigureConsole(IServiceProvider serviceProvider)
{
var logger = serviceProvider.GetRequiredService<ILogger<Startup>>();
BootstrapperLifetime.OnApplicationStartedCallback = () => logger.LogWarning("Console started.");
BootstrapperLifetime.OnApplicationStoppingCallback = () =>
var events = serviceProvider.GetRequiredService<IHostLifetimeEvents>();

events.OnApplicationStartedCallback = () =>
{
logger.LogWarning("Console started.");
};

events.OnApplicationStoppingCallback = () =>
{
logger.LogWarning("Stopping and cleaning ..");
Thread.Sleep(TimeSpan.FromSeconds(5)); // simulate graceful shutdown
logger.LogWarning(".. done!");
};
BootstrapperLifetime.OnApplicationStoppedCallback = () => logger.LogCritical("Console stopped.");

events.OnApplicationStoppedCallback = () => logger.LogCritical("Console stopped.");
}

public async override Task RunAsync(IServiceProvider serviceProvider, CancellationToken cancellationToken)
Expand Down
8 changes: 5 additions & 3 deletions app/Codebelt.Bootstrapper.MinimalConsole.App/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,16 @@ static Task Main(string[] args)
var host = builder.Build();

var logger = host.Services.GetRequiredService<ILogger<Program>>();
BootstrapperLifetime.OnApplicationStartedCallback = () => logger.LogWarning("Console started.");
BootstrapperLifetime.OnApplicationStoppingCallback = () =>
var events = host.Services.GetRequiredService<IHostLifetimeEvents>();

events.OnApplicationStartedCallback = () => logger.LogWarning("Console started.");
events.OnApplicationStoppingCallback = () =>
{
logger.LogWarning("Stopping and cleaning ..");
Thread.Sleep(TimeSpan.FromSeconds(5)); // simulate graceful shutdown
logger.LogWarning(".. done!");
};
BootstrapperLifetime.OnApplicationStoppedCallback = () => logger.LogCritical("Console stopped.");
events.OnApplicationStoppedCallback = () => logger.LogCritical("Console stopped.");

return host.RunAsync();
}
Expand Down
10 changes: 5 additions & 5 deletions app/Codebelt.Bootstrapper.MinimalWorker.App/FakeHostedService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,24 @@ public class FakeHostedService : BackgroundService
private readonly ILogger<FakeHostedService> _logger;
private bool _gracefulShutdown;

public FakeHostedService(ILogger<FakeHostedService> logger)
public FakeHostedService(ILogger<FakeHostedService> logger, IHostLifetimeEvents events)
{
_logger = logger;

BootstrapperLifetime.OnApplicationStartedCallback = () => logger.LogInformation("Started");
BootstrapperLifetime.OnApplicationStoppingCallback = () =>

events.OnApplicationStartedCallback = () => logger.LogInformation("Started");
events.OnApplicationStoppingCallback = () =>
{
_gracefulShutdown = true;
logger.LogWarning("Stopping and cleaning ..");
Thread.Sleep(TimeSpan.FromSeconds(5)); // simulate graceful shutdown
logger.LogWarning(".. done!");
};
BootstrapperLifetime.OnApplicationStoppedCallback = () => logger.LogCritical("Stopped");
events.OnApplicationStoppedCallback = () => logger.LogCritical("Stopped");
}

protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
await this.WaitForApplicationStartedAnnouncementAsync(stoppingToken).ConfigureAwait(false);
while (!stoppingToken.IsCancellationRequested)
{
if (_gracefulShutdown) { return; }
Expand Down
Loading
Loading