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
4 changes: 2 additions & 2 deletions .docfx/Dockerfile.docfx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
ARG NGINX_VERSION=1.29.3-alpine
ARG NGINX_VERSION=1.29.4-alpine

FROM --platform=$BUILDPLATFORM nginx:${NGINX_VERSION} AS base
RUN rm -rf /usr/share/nginx/html/*

FROM --platform=$BUILDPLATFORM codebeltnet/docfx:2.78.3 AS build
FROM --platform=$BUILDPLATFORM codebeltnet/docfx:2.78.4 AS build

ADD [".", "docfx"]

Expand Down
2 changes: 1 addition & 1 deletion .docfx/docfx.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
],
"globalMetadata": {
"_appTitle": "Shared Kernel (DDD) for .NET",
"_appFooter": "<span>Generated by <strong>DocFX</strong>. Copyright 2024-2025 Geekle. All rights reserved. Code with passion; love your work; deploy with confidence 👨‍💻️🔥❤️🚀😎</span>",
"_appFooter": "<span>Generated by <strong>DocFX</strong>. Copyright 2024-2026 Geekle. All rights reserved. Code with passion; love your work; deploy with confidence 👨‍💻️🔥❤️🚀😎</span>",
"_appLogoPath": "images/50x50.png",
"_appFaviconPath": "images/favicon.ico",
"_googleAnalyticsTagId": "G-NQMBRNRZ5X",
Expand Down
610 changes: 610 additions & 0 deletions .github/copilot-instructions.md

Large diffs are not rendered by default.

164 changes: 164 additions & 0 deletions .github/prompts/benchmark.prompt.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
---
mode: agent
description: 'Writing Performance Benchmarks'
---

# Benchmark Fixture Prompt (Tuning Benchmarks)

This prompt defines how to generate performance tests (“benchmarks”) for a project/solution using BenchmarkDotNet.
Benchmarks are *not* unit tests — they are micro- or component-level performance measurements that belong under the `tuning/` directory and follow strict conventions.

Copilot must follow these guidelines when generating benchmark fixtures.

---

## 1. Naming and Placement

- All benchmark projects live under the `tuning/` folder.
Examples:
- `tuning/<ProjectName>.Benchmarks/`
- `tuning/<ProjectName>.Console.Benchmarks/`

- **Namespaces must NOT end with `.Benchmarks`.**
They must mirror the production assembly’s namespace.

Example:
If benchmarking a type inside `YourProject.Console`, then:

```csharp
namespace YourProject.Console
{
public class Sha512256Benchmark { … }
}
```

* **Benchmark class names must end with `Benchmark`.**
Example: `DateSpanBenchmark`, `FowlerNollVoBenchmark`.

* Benchmark files should be located in the matching benchmark project
(e.g., benchmarks for `YourProject.Console` go in `YourProject.Console.Benchmarks.csproj`).

* In the `.csproj` for each benchmark project, set the root namespace to the production namespace, for example:

```xml
<RootNamespace>YourProject.Console</RootNamespace>
```

---

## 2. Attributes and Configuration

Each benchmark class should use:

```csharp
[MemoryDiagnoser]
[GroupBenchmarksBy(BenchmarkLogicalGroupRule.ByCategory)]
```

Optional but strongly recommended where meaningful:

* `[Params(...)]` — define small, medium, large input sizes.
* `[GlobalSetup]` — deterministic initialization of benchmark data.
* `[Benchmark(Description = "...")]` — always add descriptions.
* `[Benchmark(Baseline = true)]` — when comparing two implementations.

Avoid complex global configs; prefer explicit attributes inside the class.

---

## 3. Structure and Best Practices

A benchmark fixture must:

* Measure a **single logical operation** per benchmark method.
* Avoid I/O, networking, disk access, logging, or side effects.
* Avoid expensive setup inside `[Benchmark]` methods.
* Use deterministic data (e.g., seeded RNG or predefined constants).
* Use `[GlobalSetup]` to allocate buffers, random payloads, or reusable test data only once.
* Avoid shared mutable state unless reset per iteration.
Comment on lines +51 to +78
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Fix list indentation to satisfy markdownlint (MD005/MD007).

Several list items have inconsistent indentation. Normalize bullets to a single top-level list (no leading spaces) to keep lint green.

✏️ Proposed indentation fix
-Optional but strongly recommended where meaningful:
-
-* `[Params(...)]` — define small, medium, large input sizes.
-* `[GlobalSetup]` — deterministic initialization of benchmark data.
-* `[Benchmark(Description = "...")]` — always add descriptions.
-* `[Benchmark(Baseline = true)]` — when comparing two implementations.
+Optional but strongly recommended where meaningful:
+
+- `[Params(...)]` — define small, medium, large input sizes.
+- `[GlobalSetup]` — deterministic initialization of benchmark data.
+- `[Benchmark(Description = "...")]` — always add descriptions.
+- `[Benchmark(Baseline = true)]` — when comparing two implementations.
-A benchmark fixture must:
-
-* Measure a **single logical operation** per benchmark method.
-* Avoid I/O, networking, disk access, logging, or side effects.
-* Avoid expensive setup inside `[Benchmark]` methods.
-* Use deterministic data (e.g., seeded RNG or predefined constants).
-* Use `[GlobalSetup]` to allocate buffers, random payloads, or reusable test data only once.
-* Avoid shared mutable state unless reset per iteration.
+A benchmark fixture must:
+
+- Measure a **single logical operation** per benchmark method.
+- Avoid I/O, networking, disk access, logging, or side effects.
+- Avoid expensive setup inside `[Benchmark]` methods.
+- Use deterministic data (e.g., seeded RNG or predefined constants).
+- Use `[GlobalSetup]` to allocate buffers, random payloads, or reusable test data only once.
+- Avoid shared mutable state unless reset per iteration.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
Each benchmark class should use:
```csharp
[MemoryDiagnoser]
[GroupBenchmarksBy(BenchmarkLogicalGroupRule.ByCategory)]
```
Optional but strongly recommended where meaningful:
* `[Params(...)]` — define small, medium, large input sizes.
* `[GlobalSetup]` — deterministic initialization of benchmark data.
* `[Benchmark(Description = "...")]` — always add descriptions.
* `[Benchmark(Baseline = true)]` — when comparing two implementations.
Avoid complex global configs; prefer explicit attributes inside the class.
---
## 3. Structure and Best Practices
A benchmark fixture must:
* Measure a **single logical operation** per benchmark method.
* Avoid I/O, networking, disk access, logging, or side effects.
* Avoid expensive setup inside `[Benchmark]` methods.
* Use deterministic data (e.g., seeded RNG or predefined constants).
* Use `[GlobalSetup]` to allocate buffers, random payloads, or reusable test data only once.
* Avoid shared mutable state unless reset per iteration.
Each benchmark class should use:
🧰 Tools
🪛 markdownlint-cli2 (0.18.1)

52-52: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


66-66: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


71-71: Inconsistent indentation for list items at the same level
Expected: 0; Actual: 1

(MD005, list-indent)


71-71: Unordered list indentation
Expected: 0; Actual: 1

(MD007, ul-indent)


72-72: Inconsistent indentation for list items at the same level
Expected: 0; Actual: 1

(MD005, list-indent)


72-72: Unordered list indentation
Expected: 0; Actual: 1

(MD007, ul-indent)


73-73: Inconsistent indentation for list items at the same level
Expected: 0; Actual: 1

(MD005, list-indent)


73-73: Unordered list indentation
Expected: 0; Actual: 1

(MD007, ul-indent)


74-74: Inconsistent indentation for list items at the same level
Expected: 0; Actual: 1

(MD005, list-indent)


74-74: Unordered list indentation
Expected: 0; Actual: 1

(MD007, ul-indent)

🤖 Prompt for AI Agents
In @.github/prompts/benchmark.prompt.md around lines 51 - 78, The markdown has
inconsistent list indentation causing MD005/MD007 failures; fix by normalizing
all bullet lists to top-level (no leading spaces) under the "Each benchmark
class should use:" block (the bullets for [Params(...)], [GlobalSetup],
[Benchmark(...)]), and under the "## 3. Structure and Best Practices" section
(the list items beginning with "Measure a **single logical operation**..." etc);
remove extra leading spaces before list markers, ensure nested lists are
intentionally indented only when semantically nested, and run markdownlint to
verify MD005/MD007 are resolved.


Use representative input sizes such as:

```csharp
[Params(8, 256, 4096)]
public int Count { get; set; }
```

BenchmarkDotNet will run each benchmark for each parameter value.

---

## 4. Method Naming Conventions

Use descriptive names that communicate intent:

* `Parse_Short`
* `Parse_Long`
* `ComputeHash_Small`
* `ComputeHash_Large`
* `Serialize_Optimized`
* `Serialize_Baseline`

When comparing approaches, always list them clearly and tag one as the baseline.

---

## 5. Example Benchmark Fixture

```csharp
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Configs;

namespace YourProject
{
[MemoryDiagnoser]
[GroupBenchmarksBy(BenchmarkLogicalGroupRule.ByCategory)]
public class SampleOperationBenchmark
{
[Params(8, 256, 4096)]
public int Count { get; set; }

private byte[] _payload;

[GlobalSetup]
public void Setup()
{
_payload = new byte[Count];
// deterministic initialization
}

[Benchmark(Baseline = true, Description = "Operation - baseline")]
public int Operation_Baseline() => SampleOperation.Process(_payload);

[Benchmark(Description = "Operation - optimized")]
public int Operation_Optimized() => SampleOperation.ProcessOptimized(_payload);
}
}
```

---

## 6. Reporting and CI

* Benchmark projects live exclusively under `tuning/`. They must not affect production builds.
* Heavy BenchmarkDotNet runs should *not* run in CI unless explicitly configured.
* Reports are produced by the benchmark runner and stored under the configured artifacts directory.

---

## 7. Additional Guidelines

* Keep benchmark fixtures focused and readable.
* Document non-obvious reasoning in short comments.
* Prefer realistic but deterministic data sets.
* When benchmarks reveal regressions or improvements, reference the associated PR or issue in a comment.
* Shared benchmark helpers belong in `tuning/` projects, not in production code.

---

## Final Notes

* Benchmarks are performance tests, not unit tests.
* Use `[Benchmark]` only for pure performance measurement.
* Avoid `MethodImplOptions.NoInlining` unless absolutely necessary.
* Use small sets of meaningful benchmark scenarios — avoid combinatorial explosion.
Original file line number Diff line number Diff line change
@@ -1,12 +1,7 @@
name: Shared Kernel CI/CD Pipeline
name: Shared Kernel CI Pipeline
on:
pull_request:
branches: [main]
paths-ignore:
- .codecov/**
- .docfx/**
- .nuget/**
- '**/*.md'
workflow_dispatch:
inputs:
configuration:
Expand Down Expand Up @@ -50,7 +45,7 @@ jobs:
strategy:
fail-fast: false
matrix:
os: [ubuntu-24.04, windows-2022]
os: [ubuntu-24.04, windows-2025, ubuntu-24.04-arm, windows-11-arm]
configuration: [Debug, Release]
uses: codebeltnet/jobs-dotnet-test/.github/workflows/default.yml@v3
with:
Expand Down
6 changes: 6 additions & 0 deletions .nuget/Codebelt.SharedKernel/PackageReleaseNotes.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
Version: 0.5.1
Availability: .NET 10 and .NET 9

# ALM
- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs)

Version: 0.5.0
Availability: .NET 10 and .NET 9

Expand Down
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ 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.

## [0.5.1] - 2026-01-24

This is a service update that focuses on package dependencies.

## [0.5.0] - 2025-11-15

This is a major release that focuses on adapting the latest `.NET 10` release (LTS) in exchange for current `.NET 8` (LTS).
Expand Down
39 changes: 0 additions & 39 deletions Codebelt.SharedKernel.sln

This file was deleted.

8 changes: 8 additions & 0 deletions Codebelt.SharedKernel.slnx
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<Solution>
<Folder Name="/src/">
<Project Path="src/Codebelt.SharedKernel/Codebelt.SharedKernel.csproj" />
</Folder>
<Folder Name="/test/">
<Project Path="test/Codebelt.SharedKernel.Tests/Codebelt.SharedKernel.Tests.csproj" />
</Folder>
</Solution>
3 changes: 2 additions & 1 deletion Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
<IsMainAuthor Condition="'$(EMAIL)' == 'michael@geekle.io'">true</IsMainAuthor>
<SkipSignAssembly>false</SkipSignAssembly>
<LangVersion>latest</LangVersion>
<PackageReleaseNotesFile>..\..\.nuget\$(MSBuildProjectName)\PackageReleaseNotes.txt</PackageReleaseNotesFile>
</PropertyGroup>

<PropertyGroup Condition="'$(CI)' == 'true'">
Expand All @@ -13,7 +14,7 @@

<PropertyGroup Condition="'$(IsTestProject)' == 'false'">
<TargetFrameworks>net10.0;net9.0</TargetFrameworks>
<Copyright>Copyright © Geekle 2024-2025. All rights reserved.</Copyright>
<Copyright>Copyright © Geekle 2024-2026. All rights reserved.</Copyright>
<Authors>gimlichael</Authors>
<Company>Geekle</Company>
<Product>Codebelt Shared Kernel (DDD)</Product>
Expand Down
4 changes: 0 additions & 4 deletions Directory.Build.targets
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
<Project>
<PropertyGroup>
<PackageReleaseNotesFile>..\..\.nuget\$(MSBuildProjectName)\PackageReleaseNotes.txt</PackageReleaseNotesFile>
</PropertyGroup>

<Target Name="PreparePackageReleaseNotesFromFile" BeforeTargets="GenerateNuspec" Condition="'$(IsTestProject)' == 'false' AND Exists('$(PackageReleaseNotesFile)')">
<ReadLinesFromFile File="$(PackageReleaseNotesFile)">
<Output TaskParameter="Lines" ItemName="PackageReleaseNotesLines"/>
Expand Down
16 changes: 8 additions & 8 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,17 @@
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
</PropertyGroup>
<ItemGroup>
<PackageVersion Include="Cuemon.Extensions.IO" Version="10.0.0" />
<PackageVersion Include="Codebelt.Extensions.Xunit.App" Version="11.0.0" />
<PackageVersion Include="Cuemon.Extensions.IO" Version="10.1.2" />
<PackageVersion Include="Codebelt.Extensions.Xunit.App" Version="11.0.4" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="18.0.1" />
<PackageVersion Include="MinVer" Version="6.0.0" />
<PackageVersion Include="Savvyio.Domain" Version="5.0.0" />
<PackageVersion Include="Savvyio.Extensions.Newtonsoft.Json" Version="5.0.0" />
<PackageVersion Include="Savvyio.Extensions.Text.Json" Version="5.0.0" />
<PackageVersion Include="MinVer" Version="7.0.0" />
<PackageVersion Include="Savvyio.Domain" Version="5.0.1" />
<PackageVersion Include="Savvyio.Extensions.Newtonsoft.Json" Version="5.0.1" />
<PackageVersion Include="Savvyio.Extensions.Text.Json" Version="5.0.1" />
<PackageVersion Include="coverlet.collector" Version="6.0.4" />
<PackageVersion Include="coverlet.msbuild" Version="6.0.4" />
<PackageVersion Include="xunit.v3" Version="3.1.0" />
<PackageVersion Include="xunit.v3.runner.console" Version="3.2.0" />
<PackageVersion Include="xunit.v3" Version="3.2.2" />
<PackageVersion Include="xunit.v3.runner.console" Version="3.2.2" />
<PackageVersion Include="xunit.runner.visualstudio" Version="3.1.5" />
</ItemGroup>
</Project>
2 changes: 1 addition & 1 deletion LICENSE.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
MIT Copyright (c) 2024-2025 Geekle
MIT Copyright (c) 2024-2026 Geekle

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

Expand Down
2 changes: 1 addition & 1 deletion testenvironments.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
{
"name": "Docker-Ubuntu",
"type": "docker",
"dockerImage": "gimlichael/ubuntu-testrunner:net8.0.416-9.0.307-10.0.100"
"dockerImage": "gimlichael/ubuntu-testrunner:net8.0.417-9.0.309-10.0.102"
}
]
}
Loading