Conversation
|
Warning Rate limit exceeded
⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. 📒 Files selected for processing (2)
📝 WalkthroughWalkthroughAdds a new Codebelt.Extensions.Carter library with configurable response negotiators (System.Text.Json, Newtonsoft.Json, YAML, XML), endpoint metadata helpers, tests, DocFX docs and Docker publishing tooling, GitHub workflows/automation, and repository build/package configuration. Changes
Sequence Diagram(s)mermaid %% colored rectangles for components Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Poem
🚥 Pre-merge checks | ✅ 1 | ❌ 2❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (1 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Pull request overview
This PR bootstraps the initial “Extensions for Carter by Codebelt” repository with core Carter extension APIs (response negotiators + endpoint metadata helpers), accompanying unit/functional tests, and the release/documentation/CI infrastructure needed to publish and maintain the packages.
Changes:
- Added core Carter extension library and format-specific response negotiator packages (System.Text.Json, Newtonsoft.Json, YAML, XML).
- Added unit + functional test projects to validate negotiator behavior and endpoint metadata conventions.
- Added repo-wide infrastructure: central package management, build props/targets, CI workflows, DocFX site generation, NuGet metadata/assets, and project docs/policies.
Reviewed changes
Copilot reviewed 71 out of 80 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| testenvironments.json | Defines WSL/Docker test environments. |
| test/Codebelt.Extensions.Carter.Tests/Response/ConfigurableResponseNegotiatorTest.cs | Unit tests for configurable negotiator base behavior. |
| test/Codebelt.Extensions.Carter.Tests/EndpointConventionBuilderExtensionsTest.cs | Unit tests for endpoint convention metadata extensions. |
| test/Codebelt.Extensions.Carter.Tests/Codebelt.Extensions.Carter.Tests.csproj | Unit test project scaffold for core extensions. |
| test/Codebelt.Extensions.Carter.FunctionalTests/YamlResponseNegotiatorTest.cs | Functional test for YAML negotiator integration. |
| test/Codebelt.Extensions.Carter.FunctionalTests/XmlResponseNegotiatorTest.cs | Functional test for XML negotiator integration. |
| test/Codebelt.Extensions.Carter.FunctionalTests/NewtonsoftJsonNegotiatorTest.cs | Functional test for Newtonsoft JSON negotiator integration. |
| test/Codebelt.Extensions.Carter.FunctionalTests/JsonResponseNegotiatorTest.cs | Functional test for System.Text.Json negotiator integration. |
| test/Codebelt.Extensions.Carter.FunctionalTests/Codebelt.Extensions.Carter.FunctionalTests.csproj | Functional test project scaffold. |
| test/Codebelt.Extensions.Carter.FunctionalTests/Assets/WorldModule.cs | Test Carter module used by functional tests. |
| test/Codebelt.Extensions.Carter.AspNetCore.Xml.Tests/XmlResponseNegotiatorTest.cs | Unit/hosted test coverage for XML negotiator. |
| test/Codebelt.Extensions.Carter.AspNetCore.Xml.Tests/Codebelt.Extensions.Carter.AspNetCore.Xml.Tests.csproj | XML negotiator test project scaffold. |
| test/Codebelt.Extensions.Carter.AspNetCore.Text.Yaml.Tests/YamlResponseNegotiatorTest.cs | Unit/hosted test coverage for YAML negotiator. |
| test/Codebelt.Extensions.Carter.AspNetCore.Text.Yaml.Tests/Codebelt.Extensions.Carter.AspNetCore.Text.Yaml.Tests.csproj | YAML negotiator test project scaffold. |
| test/Codebelt.Extensions.Carter.AspNetCore.Text.Json.Tests/JsonResponseNegotiatorTest.cs | Unit/hosted test coverage for System.Text.Json negotiator. |
| test/Codebelt.Extensions.Carter.AspNetCore.Text.Json.Tests/Codebelt.Extensions.Carter.AspNetCore.Text.Json.Tests.csproj | System.Text.Json negotiator test project scaffold. |
| test/Codebelt.Extensions.Carter.AspNetCore.Newtonsoft.Json.Tests/NewtonsoftJsonNegotiatorTest.cs | Unit/hosted test coverage for Newtonsoft negotiator. |
| test/Codebelt.Extensions.Carter.AspNetCore.Newtonsoft.Json.Tests/Codebelt.Extensions.Carter.AspNetCore.Newtonsoft.Json.Tests.csproj | Newtonsoft negotiator test project scaffold. |
| src/Codebelt.Extensions.Carter/Response/ConfigurableResponseNegotiator.cs | Adds configurable base class for response negotiators. |
| src/Codebelt.Extensions.Carter/EndpointConventionBuilderExtensions.cs | Adds endpoint metadata helper extensions. |
| src/Codebelt.Extensions.Carter/Codebelt.Extensions.Carter.csproj | Core package metadata + references. |
| src/Codebelt.Extensions.Carter.AspNetCore.Xml/XmlResponseNegotiator.cs | XML response negotiator implementation. |
| src/Codebelt.Extensions.Carter.AspNetCore.Xml/Codebelt.Extensions.Carter.AspNetCore.Xml.csproj | XML package metadata + references. |
| src/Codebelt.Extensions.Carter.AspNetCore.Text.Yaml/YamlResponseNegotiator.cs | YAML response negotiator implementation. |
| src/Codebelt.Extensions.Carter.AspNetCore.Text.Yaml/Codebelt.Extensions.Carter.AspNetCore.Text.Yaml.csproj | YAML package metadata + references. |
| src/Codebelt.Extensions.Carter.AspNetCore.Text.Json/JsonResponseNegotiator.cs | System.Text.Json response negotiator implementation. |
| src/Codebelt.Extensions.Carter.AspNetCore.Text.Json/Codebelt.Extensions.Carter.AspNetCore.Text.Json.csproj | System.Text.Json package metadata + references. |
| src/Codebelt.Extensions.Carter.AspNetCore.Newtonsoft.Json/NewtonsoftJsonNegotiator.cs | Newtonsoft.Json response negotiator implementation. |
| src/Codebelt.Extensions.Carter.AspNetCore.Newtonsoft.Json/Codebelt.Extensions.Carter.AspNetCore.Newtonsoft.Json.csproj | Newtonsoft package metadata + references. |
| README.md | Repository overview + usage examples and package list. |
| LICENSE | MIT license text. |
| Directory.Packages.props | Central package version management. |
| Directory.Build.targets | Release notes + file version targets. |
| Directory.Build.props | Repo-wide MSBuild conventions for src/test/bench/tooling. |
| Codebelt.Extensions.Carter.slnx | Solution definition for src + test projects. |
| CHANGELOG.md | Initial changelog entry. |
| .nuget/Codebelt.Extensions.Carter/icon.png | NuGet package icon asset. |
| .nuget/Codebelt.Extensions.Carter/README.md | NuGet readme for core package. |
| .nuget/Codebelt.Extensions.Carter/PackageReleaseNotes.txt | NuGet release notes for core package. |
| .nuget/Codebelt.Extensions.Carter.AspNetCore.Xml/icon.png | NuGet package icon asset (XML). |
| .nuget/Codebelt.Extensions.Carter.AspNetCore.Xml/README.md | NuGet readme (XML package). |
| .nuget/Codebelt.Extensions.Carter.AspNetCore.Xml/PackageReleaseNotes.txt | NuGet release notes (XML package). |
| .nuget/Codebelt.Extensions.Carter.AspNetCore.Text.Yaml/icon.png | NuGet package icon asset (YAML). |
| .nuget/Codebelt.Extensions.Carter.AspNetCore.Text.Yaml/README.md | NuGet readme (YAML package). |
| .nuget/Codebelt.Extensions.Carter.AspNetCore.Text.Yaml/PackageReleaseNotes.txt | NuGet release notes (YAML package). |
| .nuget/Codebelt.Extensions.Carter.AspNetCore.Text.Json/icon.png | NuGet package icon asset (System.Text.Json). |
| .nuget/Codebelt.Extensions.Carter.AspNetCore.Text.Json/README.md | NuGet readme (System.Text.Json package). |
| .nuget/Codebelt.Extensions.Carter.AspNetCore.Text.Json/PackageReleaseNotes.txt | NuGet release notes (System.Text.Json package). |
| .nuget/Codebelt.Extensions.Carter.AspNetCore.Newtonsoft.Json/icon.png | NuGet package icon asset (Newtonsoft). |
| .nuget/Codebelt.Extensions.Carter.AspNetCore.Newtonsoft.Json/README.md | NuGet readme (Newtonsoft package). |
| .nuget/Codebelt.Extensions.Carter.AspNetCore.Newtonsoft.Json/PackageReleaseNotes.txt | NuGet release notes (Newtonsoft package). |
| .gitignore | Standard VS/.NET ignores + DocFX/tooling ignores. |
| .github/workflows/trigger-downstream.yml | Dispatch downstream updates on release publish. |
| .github/workflows/service-update.yml | Automated “service update” workflow (dependency bumps + PR). |
| .github/workflows/scorecard.yml | OSSF Scorecard workflow. |
| .github/workflows/ci-pipeline.yml | CI pipeline using reusable workflows for build/test/scan/deploy. |
| .github/scripts/bump-nuget.py | Script to bump only source-owned packages for service updates. |
| .github/dispatch-targets.json | Placeholder list for downstream dispatch targets. |
| .github/dependabot.yml | Dependabot configuration (NuGet + GitHub Actions). |
| .github/copilot-instructions.md | Repository guidance for tests/benchmarks/docs. |
| .github/codecov.yml | Codecov config (ignores test folder). |
| .github/CONTRIBUTING.md | Contributor guidelines. |
| .github/CODE_OF_CONDUCT.md | Contributor Covenant code of conduct. |
| .editorconfig | Repo-wide formatting/style/analyzer configuration. |
| .docfx/toc.yml | DocFX site TOC. |
| .docfx/index.md | DocFX front page. |
| .docfx/includes/availability-modern.md | Shared include for availability note. |
| .docfx/images/50x50.png | DocFX image asset. |
| .docfx/images/32x32.png | DocFX image asset. |
| .docfx/images/favicon.ico | DocFX favicon asset. |
| .docfx/filterConfig.yml | DocFX API filter configuration. |
| .docfx/docfx.json | DocFX metadata/build configuration. |
| .docfx/api/namespaces/Codebelt.Extensions.Carter.md | Namespace landing page for core package. |
| .docfx/api/namespaces/Codebelt.Extensions.Carter.AspNetCore.Xml.md | Namespace landing page for XML package. |
| .docfx/api/namespaces/Codebelt.Extensions.Carter.AspNetCore.Text.Yaml.md | Namespace landing page for YAML package. |
| .docfx/api/namespaces/Codebelt.Extensions.Carter.AspNetCore.Text.Json.md | Namespace landing page for System.Text.Json package. |
| .docfx/api/namespaces/Codebelt.Extensions.Carter.AspNetCore.Newtonsoft.Json.md | Namespace landing page for Newtonsoft package. |
| .docfx/PublishDocfxImage.ps1 | Script to tag/push DocFX site image. |
| .docfx/Dockerfile.docfx | Docker-based DocFX site build + nginx runtime image. |
| .docfx/BuildDocfxImage.ps1 | Script to build DocFX artifacts and docker image. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
test/Codebelt.Extensions.Carter.Tests/Response/ConfigurableResponseNegotiatorTest.cs
Show resolved
Hide resolved
src/Codebelt.Extensions.Carter/Response/ConfigurableResponseNegotiator.cs
Show resolved
Hide resolved
src/Codebelt.Extensions.Carter/Response/ConfigurableResponseNegotiator.cs
Show resolved
Hide resolved
...Codebelt.Extensions.Carter.FunctionalTests/Codebelt.Extensions.Carter.FunctionalTests.csproj
Show resolved
Hide resolved
There was a problem hiding this comment.
Actionable comments posted: 10
Note
Due to the large number of review comments, Critical, Major severity comments were prioritized as inline comments.
🟡 Minor comments (12)
.editorconfig-177-187 (1)
177-187:⚠️ Potential issue | 🟡 MinorRemove duplicated IDE0036 block.
The
IDE0036section is duplicated (Line 177–181 and Line 183–187). Keep one to reduce config drift and ambiguity.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.editorconfig around lines 177 - 187, Remove the duplicated IDE0036 configuration block in .editorconfig by keeping a single [*.{cs,vb}] section that sets dotnet_diagnostic.IDE0036.severity = none and deleting the repeated duplicate; ensure the remaining block includes the comment lines (Order modifiers and link) and the single dotnet_diagnostic.IDE0036.severity entry so only one IDE0036 declaration exists..editorconfig-3-8 (1)
3-8:⚠️ Potential issue | 🟡 MinorAdd a Markdown override for trailing whitespace.
Line 7 applies
trim_trailing_whitespace = trueglobally, which can remove intentional Markdown hard line breaks in docs. Consider overriding for*.md.Proposed tweak
[*] charset = utf-8 end_of_line = lf insert_final_newline = true trim_trailing_whitespace = true +[*.md] +trim_trailing_whitespace = false🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.editorconfig around lines 3 - 8, Add an .editorconfig override for Markdown files so intentional hard line breaks aren't stripped: add a section for the glob [*.md] that sets trim_trailing_whitespace = false (and optionally end_of_line and insert_final_newline as desired) to override the global trim_trailing_whitespace = true; update the file to include this [*.md] block so Markdown files preserve trailing spaces while keeping the global rule for other files..editorconfig-105-113 (1)
105-113:⚠️ Potential issue | 🟡 MinorFix comment IDs in .editorconfig to match configured diagnostics.
Lines 105 and 110 contain incorrect analyzer IDs in the comments. The configured diagnostics are
IDE0300andIDE0301, but the comments referenceIDE0039andIDE0031. Correct the comments to match the actual rule IDs being configured.Proposed correction
-# IDE0039: Use collection expression for array +# IDE0300: Use collection expression for array # https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0300 [*.{cs,vb}] dotnet_diagnostic.IDE0300.severity = none -# IDE0031: Use collection expression for empty +# IDE0301: Use collection expression for empty # https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0301 [*.{cs,vb}] dotnet_diagnostic.IDE0301.severity = none🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.editorconfig around lines 105 - 113, Update the two comment lines that reference analyzer IDs so they match the configured diagnostics: change the comment "IDE0039: Use collection expression for array" to "IDE0300: Use collection expression for array" and change "IDE0031: Use collection expression for empty" to "IDE0301: Use collection expression for empty" so the comments align with the dotnet_diagnostic IDE0300 and IDE0301 settings in the .editorconfig; locate the comments adjacent to the blocks that configure dotnet_diagnostic.IDE0300.severity = none and dotnet_diagnostic.IDE0301.severity = none (the comment texts are the unique identifiers to edit)..github/dependabot.yml-1-17 (1)
1-17:⚠️ Potential issue | 🟡 MinorNormalize file line endings to LF to satisfy linting.
YAMLlint flags this file at Line 1 due to CRLF line endings. Convert this file to LF (
\n) to avoid CI lint failures.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.github/dependabot.yml around lines 1 - 17, The file has CRLF line endings causing YAML lint failures; convert .github/dependabot.yml to use LF (\n) line endings throughout (ensure the top-level keys like "version: 2" and "updates:" and the package-ecosystem entries remain unchanged) — update your editor or run a normalization (e.g., dos2unix or git config core.autocrlf=false then re-checkout) so the file is saved with LF endings and re-run linting to confirm the error is resolved..nuget/Codebelt.Extensions.Carter.AspNetCore.Text.Yaml/PackageReleaseNotes.txt-3-6 (1)
3-6:⚠️ Potential issue | 🟡 MinorReplace non-breaking spaces in blank lines.
Line 3 and Line 6 appear to use non-breaking spaces instead of plain empty lines, which can cause inconsistent rendering in some tooling.
🧹 Proposed normalization
Version: 1.0.0 Availability: .NET 10 - + # New Features - ADDED YamlResponseNegotiator class in the Codebelt.Extensions.Carter.AspNetCore.Text.Yaml namespace that provides a YAML response negotiator for Carter, capable of serializing response models to YAML format using YamlDotNet - +🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.nuget/Codebelt.Extensions.Carter.AspNetCore.Text.Yaml/PackageReleaseNotes.txt around lines 3 - 6, Two blank lines in PackageReleaseNotes.txt contain non-breaking spaces (NBSP) instead of true empty lines; open the file and remove the U+00A0 characters on the affected blank lines so they become plain empty lines (ensure lines reported around the "# New Features" section are just newline characters), then save with normal whitespace/UTF-8 encoding so tools render the blank lines correctly.README.md-107-108 (1)
107-108:⚠️ Potential issue | 🟡 MinorIncorrect package description.
The description "Provides a focused API for BenchmarkDotNet projects" appears to be a copy-paste error. This section describes Carter extension packages for response negotiation, not BenchmarkDotNet.
Proposed fix
## 📦 Standalone Packages -Provides a focused API for BenchmarkDotNet projects. +Provides standalone response negotiator packages that extend Carter with specific content negotiation capabilities.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@README.md` around lines 107 - 108, The package description string "Provides a focused API for BenchmarkDotNet projects" is incorrect; replace that sentence in the README (the package description line) with an accurate description for the Carter negotiation extension packages, e.g. a short line stating these packages "Provide Carter extensions for response content negotiation (media type negotiation, formatters, and helpers)"; update only the offending sentence so it clearly references Carter response negotiation rather than BenchmarkDotNet..docfx/Dockerfile.docfx-3-4 (1)
3-4:⚠️ Potential issue | 🟡 MinorUnused
basestage.The
basestage is defined but never referenced in subsequentCOPY --from=orFROMdirectives. Thefinalstage directly usesnginx:${NGINX_VERSION}, making thebasestage dead code.Proposed fix to remove unused stage
ARG NGINX_VERSION=1.29.5-alpine -FROM --platform=$BUILDPLATFORM nginx:${NGINX_VERSION} AS base -RUN rm -rf /usr/share/nginx/html/* - FROM --platform=$BUILDPLATFORM codebeltnet/docfx:2.78.5 AS build ADD [".", "docfx"]🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.docfx/Dockerfile.docfx around lines 3 - 4, The Dockerfile defines an unused build stage named "base" (FROM ... AS base and its RUN) which is never referenced by any COPY --from= or by the final stage that uses nginx:${NGINX_VERSION}; remove the dead "base" stage to avoid confusion and reduce image complexity, or alternatively change the final stage to use FROM base (and update any COPY --from= references) if the intent was to seed the final image from that stage; locate the "base" stage declaration and either delete those lines or update the final stage to reference "base" accordingly..github/workflows/ci-pipeline.yml-1-117 (1)
1-117:⚠️ Potential issue | 🟡 MinorNormalize file line endings to LF to satisfy YAML linting.
Static analysis reports newline style violations (
expected \n), which can fail CI lint checks even when workflow logic is correct.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.github/workflows/ci-pipeline.yml around lines 1 - 117, The YAML file "Carter CI Pipeline" has CRLF line endings causing YAML lint failures; convert this workflow (.github/workflows/ci-pipeline.yml) to use LF line endings, ensure the entire file (including top-level fields like name, on, permissions and job blocks build, pack, test_linux, test_windows, sonarcloud, codecov, codeql, deploy) is normalized to LF, and add/commit the change (optionally add a .gitattributes entry like "*.yml text eol=lf" to enforce LF for CI YAML files)..nuget/Codebelt.Extensions.Carter.AspNetCore.Text.Yaml/README.md-19-31 (1)
19-31:⚠️ Potential issue | 🟡 MinorAvoid repository-internal symbols in the NuGet README sample.
The sample uses
Codebelt.Extensions.Carter.AssetsandWorldModule, which are defined only in test code and marked asinternal. These symbols are unavailable to package consumers and will cause copy/paste failures. Replace with a self-contained, public module example in the README.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.nuget/Codebelt.Extensions.Carter.AspNetCore.Text.Yaml/README.md around lines 19 - 31, The README sample references repository-internal symbols (Codebelt.Extensions.Carter.Assets, WorldModule, MinimalWebHostTestFactory.RunAsync) and an internal test-only module which will break for NuGet consumers; replace those with a self-contained, public example: remove usages of Codebelt.Extensions.Carter.Assets and WorldModule, substitute a simple public Carter module (e.g., a public class MyPublicModule : Carter.Module with a GET route) and a minimal host creation pattern instead of MinimalWebHostTestFactory.RunAsync, and keep the relevant API calls shown (services.AddMinimalYamlOptions(), services.AddCarter(...).WithResponseNegotiator<YamlResponseNegotiator>()) so the README demonstrates a copy/paste-able example using only public, package-exported types..github/workflows/service-update.yml-73-74 (1)
73-74:⚠️ Potential issue | 🟡 MinorPotential issue with
printfand variable containing literal\n.Line 74 uses
printf "$ENTRY"where$ENTRYcontains literal\nsequences. This works becauseprintfinterprets escape sequences in the format string. However, if$ENTRYever contains%characters (e.g., from the TFM string), it could cause unexpected behavior. Consider usingecho -eorprintf '%b'for clarity.🔧 Proposed safer alternative
- ENTRY="Version: ${NEW}\nAvailability: ${TFM}\n \n# ALM\n- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs)\n \n" - { printf "$ENTRY"; cat "$f"; } > "$f.tmp" && mv "$f.tmp" "$f" + ENTRY="Version: ${NEW} +Availability: ${TFM} + +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) + +" + { printf '%s' "$ENTRY"; cat "$f"; } > "$f.tmp" && mv "$f.tmp" "$f"🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.github/workflows/service-update.yml around lines 73 - 74, The ENTRY variable is passed directly to printf as a format string (printf "$ENTRY"), which can misbehave if ENTRY contains percent signs; update the write step to treat ENTRY as data rather than a format: change the printf invocation that references ENTRY to use a safe form that expands backslash escapes but does not treat percent signs as format specifiers (e.g., use printf '%b' with ENTRY or use echo -e), keeping the surrounding pipeline that writes { printf ...; cat "$f"; } > "$f.tmp" && mv "$f.tmp" "$f" intact and still referencing ENTRY and f.src/Codebelt.Extensions.Carter.AspNetCore.Newtonsoft.Json/NewtonsoftJsonNegotiator.cs-19-19 (1)
19-19:⚠️ Potential issue | 🟡 MinorAdd explicit null-guard for constructor argument.
Failing fast with
ArgumentNullExceptiongives clearer diagnostics than relying on indirect null dereference behavior.🛡️ Proposed fix
- public NewtonsoftJsonNegotiator(IOptions<NewtonsoftJsonFormatterOptions> options) : base(options.Value) + public NewtonsoftJsonNegotiator(IOptions<NewtonsoftJsonFormatterOptions> options) + : base((options ?? throw new System.ArgumentNullException(nameof(options))).Value) { }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/Codebelt.Extensions.Carter.AspNetCore.Newtonsoft.Json/NewtonsoftJsonNegotiator.cs` at line 19, The constructor for NewtonsoftJsonNegotiator should guard the incoming IOptions<NewtonsoftJsonFormatterOptions> parameter against null and throw an ArgumentNullException rather than relying on base(options.Value) to fail later; add an explicit null-check at the start of the NewtonsoftJsonNegotiator(IOptions<NewtonsoftJsonFormatterOptions> options) constructor and throw new ArgumentNullException(nameof(options)) if null, then pass options.Value to the base constructor as before.CHANGELOG.md-5-5 (1)
5-5:⚠️ Potential issue | 🟡 MinorMinor grammar fix: hyphenate "per-assembly".
Use a hyphen when "per" is used as a prefix with a noun in compound adjective form.
📝 Proposed fix
-For more details, please refer to `PackageReleaseNotes.txt` on a per assembly basis in the `.nuget` folder. +For more details, please refer to `PackageReleaseNotes.txt` on a per-assembly basis in the `.nuget` folder.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@CHANGELOG.md` at line 5, The sentence in CHANGELOG.md uses "per assembly basis" and should hyphenate the compound adjective; change "on a per assembly basis" to "on a per-assembly basis" so the phrase correctly uses the hyphenated modifier when referring to `PackageReleaseNotes.txt` in the `.nuget` folder.
🧹 Nitpick comments (16)
.github/CONTRIBUTING.md (1)
19-21: Tighten PR checklist wording for clarity.Line 19–21 has a few grammar/word-choice issues (
requires→require,test passes→tests pass,heartfulis uncommon here). Recommend a quick wording cleanup to keep contributor guidance unambiguous and polished.Suggested wording
-3. Any changes or additions requires documentation in the form of documenting public members -4. Ensure that all existing as well as new test passes -5. Issue that pull request with a big and heartful thanks for contributing +3. Any changes or additions require documentation for affected public members. +4. Ensure that all existing and new tests pass. +5. Open the pull request — and thank you for contributing.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.github/CONTRIBUTING.md around lines 19 - 21, Update the PR checklist wording in .github/CONTRIBUTING.md (the bullet items that currently read "Any changes or additions requires documentation in the form of documenting public members", "Ensure that all existing as well as new test passes", and "Issue that pull request with a big and heartful thanks for contributing") to correct grammar and word choice: change "requires" to "require", change "test passes" to "tests pass", and replace "heartful" with "heartfelt" (or "warm") and adjust surrounding phrasing so each checklist item reads clearly and grammatically correct.testenvironments.json (3)
1-1: Consider adding a JSON schema reference for IDE validation.Adding a
$schemaproperty would enable better IDE support with auto-completion and validation. This is especially helpful for test environment configurations.📋 Suggested enhancement
{ + "$schema": "https://json.schemastore.org/testenvironments.json", "version": "1", "environments": [🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@testenvironments.json` at line 1, Add a top-level "$schema" property to the JSON document (in testenvironments.json) so IDEs can validate and offer autocomplete; modify the root object creation (where the file currently begins with "{") to include a "$schema" key whose value points to the appropriate JSON Schema URI (for example a local or standard schema for your test env format) so editors can pick up validation and suggestions.
7-7: Verify WSL distribution availability across the team.The Ubuntu-24.04 WSL distribution may not be installed on all developer machines. Consider documenting the setup requirement or providing an installation guide to ensure consistent test environment availability.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@testenvironments.json` at line 7, The WSL distribution "Ubuntu-24.04" referenced by the wslDistribution setting may not exist on all developer machines; update project docs and/or CI docs to state this requirement and add an installation or fallback instruction: document that the testenvironments.json key "wslDistribution" must be installed, include the exact distribution name ("Ubuntu-24.04") and provide step-by-step WSL install commands (or recommend an alternative distribution and how to change the wslDistribution value) so team members can reproduce the test environment reliably.
12-12: LGTM: Version-pinned Docker image ensures reproducible tests.The specific version tags in the Docker image provide reproducible test environments across different machines and CI/CD pipelines. Be aware that these versions will need periodic updates to stay current with .NET releases.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@testenvironments.json` at line 12, The docker image is already version-pinned under the "dockerImage" key with value "codebeltnet/ubuntu-testrunner:net8.0.418-9.0.311-10.0.103" which is correct for reproducible tests; no change required now—keep the exact tag but add a periodic reminder or task to update these .NET version tags (for example in your release/maintenance checklist) so the "dockerImage" value is reviewed and updated when new .NET patch or major releases are adopted..docfx/toc.yml (1)
1-4: Fix line ending characters for cross-platform consistency.YAMLlint reports wrong newline characters (expected
\n). This typically indicates CRLF (\r\n) line endings instead of Unix-style LF (\n). Consider normalizing line endings for consistency across platforms and CI environments.You can fix this by configuring your editor to use LF line endings or adding a
.gitattributesrule:*.yml text eol=lf🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.docfx/toc.yml around lines 1 - 4, The .docfx/toc.yml file (containing entries "Carter API" and "NuGet") has CRLF line endings which fail YAMLlint; convert this file to use Unix LF line endings, commit the normalized file, and ensure your editor/IDE is set to save .yml files with LF; additionally add a repository-wide rule (e.g. a .gitattributes entry forcing eol=lf for *.yml) so future commits preserve LF across CI and developer machines..github/codecov.yml (1)
1-2: Consider using a more precise ignore pattern and fix line endings.
The ignore pattern
"test"may be overly broad, matching any path containing "test" (e.g.,contest,testing). A glob pattern like"test/**"or"**/test/**"would be more precise.YAMLlint flags wrong newline characters (same issue as
toc.yml).Suggested fix
ignore: - - "test" + - "test/**"🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.github/codecov.yml around lines 1 - 2, Update the ignore pattern under the ignore key to a more precise glob such as "test/**" or "**/test/**" instead of "test" to avoid matching unintended paths, and normalize the file's line endings to LF (fix the same newline character issue flagged by yamllint); after making these changes run a YAML linter/validator to confirm the YAML is valid and the newline issue is resolved..github/copilot-instructions.md (1)
300-301: XML documentation example uses external namespace.The example code uses
namespace Cuemon.Securityrather than a namespace from this project (Codebelt.Extensions.Carter.*). While the code demonstrates proper XML documentation style, using a project-specific example would be more consistent with the rest of the document.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.github/copilot-instructions.md around lines 300 - 301, The XML documentation example incorrectly uses an external namespace (namespace Cuemon.Security); update the example to use a project-specific namespace (e.g., namespace Codebelt.Extensions.Carter.Security or the consistent Codebelt.Extensions.Carter.* pattern used in the repo) so it aligns with other examples; locate the namespace declaration in the example block (the line containing "namespace Cuemon.Security") and replace it with the appropriate Codebelt.Extensions.Carter.* namespace while keeping the rest of the XML documentation example unchanged..docfx/Dockerfile.docfx (1)
8-8: UseCOPYinstead ofADDfor local files.
ADDhas extra functionality (URL fetching, tar extraction) that isn't needed here. UsingCOPYis more explicit and follows Docker best practices for copying local files.Proposed fix
-ADD [".", "docfx"] +COPY [".", "docfx"]🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.docfx/Dockerfile.docfx at line 8, Replace the ADD instruction used to copy local files (the line containing ADD [".", "docfx"]) with a COPY instruction so the Dockerfile uses COPY [".", "docfx"] instead of ADD; this removes unnecessary ADD behavior (tar extraction/URL fetch) and follows Docker best practices for copying local files..docfx/filterConfig.yml (1)
1-4: Consider using Unix-style line endings (LF).YAMLlint reports the file uses Windows-style line endings (CRLF). For consistency and cross-platform compatibility, consider converting to Unix-style line endings (LF). This can be enforced via
.gitattributesor editor settings.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.docfx/filterConfig.yml around lines 1 - 4, The YAML file defining apiRules (contains keys like apiRules, exclude, uidRegex: ^System\.Object and type: Type) uses Windows CRLF line endings; convert the file to Unix-style LF line endings (e.g., via your editor “save with LF”, dos2unix, or git config core.autocrlf=false) and commit the normalized file so YAML linting passes; optionally add or update .gitattributes to enforce LF for .yml files to prevent future CRLFs..github/scripts/bump-nuget.py (1)
130-130: Simplify redundant ternary expression.The conditional
return 0 if changes else 0always returns0regardless of the condition. This is flagged by static analysis (RUF034).🔧 Proposed fix
- return 0 if changes else 0 # Return 0 even if no changes (not an error) + return 0 # Return 0 even if no changes (not an error)🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.github/scripts/bump-nuget.py at line 130, The return statement uses a redundant conditional expression in bump_nuget.py: replace the unnecessary ternary "return 0 if changes else 0" with a simple "return 0" to eliminate the dead conditional; locate the return inside the function handling changes (the same scope that currently uses the variable changes) and simplify it to a single unconditional return value.src/Codebelt.Extensions.Carter.AspNetCore.Text.Yaml/Codebelt.Extensions.Carter.AspNetCore.Text.Yaml.csproj (1)
5-5: Consider adding "codebelt" to PackageTags for consistency.The Text.Json project includes "codebelt" in its PackageTags, but this project omits it. Adding it would improve discoverability and maintain consistency across the extension packages.
🔧 Proposed fix
- <PackageTags>extension-methods extensions carter response-negotiation yaml yamldotnet asp-net-core minimal-api</PackageTags> + <PackageTags>extension-methods extensions carter response-negotiation yaml yamldotnet asp-net-core minimal-api codebelt</PackageTags>🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/Codebelt.Extensions.Carter.AspNetCore.Text.Yaml/Codebelt.Extensions.Carter.AspNetCore.Text.Yaml.csproj` at line 5, The PackageTags element in Codebelt.Extensions.Carter.AspNetCore.Text.Yaml.csproj is missing the "codebelt" tag; update the <PackageTags> value (the PackageTags XML element) to include "codebelt" alongside the existing tags (e.g., add it to "extension-methods extensions carter response-negotiation yaml yamldotnet asp-net-core minimal-api") so the package tag list matches the other Text.* extension projects for consistency and discoverability.test/Codebelt.Extensions.Carter.FunctionalTests/Assets/WorldModule.cs (1)
17-19: Make response ordering deterministic before serialization.Stabilizing order helps avoid flaky assertions and inconsistent payload ordering across environments.
♻️ Proposed change
app.MapGet("/world/statistical-regions", (HttpResponse res, CancellationToken ct) => res.Negotiate(World.StatisticalRegions .Where(r => r.Kind == StatisticalRegionKind.World) + .OrderBy(r => r.Code) .Select(r => new StatisticalRegionModel { Code = r.Code, Name = r.Name, Kind = r.Kind }), ct));🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@test/Codebelt.Extensions.Carter.FunctionalTests/Assets/WorldModule.cs` around lines 17 - 19, The response currently projects World.StatisticalRegions into StatisticalRegionModel and negotiates it via res.Negotiate but does not enforce a deterministic ordering; to fix, sort the sequence before projection (e.g., OrderBy on a stable key such as r.Code or r.Name) so that the enumerable passed to res.Negotiate is consistently ordered; update the LINQ pipeline around World.StatisticalRegions.Where(...).Select(...) to include an OrderBy (or ThenBy) before Select to guarantee stable ordering in the returned StatisticalRegionModel sequence.test/Codebelt.Extensions.Carter.FunctionalTests/Codebelt.Extensions.Carter.FunctionalTests.csproj (1)
8-10: Remove the staleNewFolderexclusion block.The
NewFolderdirectory no longer exists in the repository, making these exclusion rules obsolete project noise. Removing lines 8-10 will clean up the configuration without any functional impact.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@test/Codebelt.Extensions.Carter.FunctionalTests/Codebelt.Extensions.Carter.FunctionalTests.csproj` around lines 8 - 10, Remove the stale exclusion entries referencing the non-existent NewFolder by deleting the three project lines containing Compile Remove="NewFolder\**", EmbeddedResource Remove="NewFolder\**" and None Remove="NewFolder\**" from the .csproj so the file no longer contains those obsolete rules.test/Codebelt.Extensions.Carter.AspNetCore.Newtonsoft.Json.Tests/NewtonsoftJsonNegotiatorTest.cs (1)
94-98: Consider adding nullable annotation toNameproperty.The
Nameproperty is a non-nullablestringwith aninitaccessor but no default value. If left uninitialized, it will benullat runtime, which may cause issues with serializers expecting non-null values.♻️ Proposed fix
internal sealed class FakeModel { public int Id { get; init; } - public string Name { get; init; } + public string? Name { get; init; } }Alternatively, provide a default value:
- public string Name { get; init; } + public string Name { get; init; } = string.Empty;🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@test/Codebelt.Extensions.Carter.AspNetCore.Newtonsoft.Json.Tests/NewtonsoftJsonNegotiatorTest.cs` around lines 94 - 98, The FakeModel.Name property is declared as non-nullable string but has no initializer, so mark it explicitly nullable or give it a default to avoid possible nulls at runtime; update the FakeModel class by changing the Name property's type to string? (nullable) or initialize it (e.g., Name = string.Empty) so serializers won't encounter an uninitialized null—refer to FakeModel and the Name property when making the change.src/Codebelt.Extensions.Carter.AspNetCore.Xml/XmlResponseNegotiator.cs (1)
13-13: Inconsistent indentation on class declaration.There's extra indentation before the
public classdeclaration that doesn't match the namespace block style.📝 Proposed fix
/// <seealso cref="ConfigurableResponseNegotiator{TOptions}"/> - public class XmlResponseNegotiator : ConfigurableResponseNegotiator<XmlFormatterOptions> + public class XmlResponseNegotiator : ConfigurableResponseNegotiator<XmlFormatterOptions> {🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/Codebelt.Extensions.Carter.AspNetCore.Xml/XmlResponseNegotiator.cs` at line 13, Remove the extra leading indentation before the class declaration so the "public class XmlResponseNegotiator : ConfigurableResponseNegotiator<XmlFormatterOptions>" line aligns with the surrounding namespace block style; locate the XmlResponseNegotiator class declaration and adjust its indentation to match the file's namespace/class formatting convention.test/Codebelt.Extensions.Carter.Tests/Response/ConfigurableResponseNegotiatorTest.cs (1)
134-142: Consider usingleaveOpen: truefor the StreamWriter.The StreamWriter wraps the MemoryStream but isn't disposed. While this works because
Flush()is called explicitly and the caller manages the stream lifecycle, using theleaveOpenparameter makes the intent explicit.♻️ Optional improvement for clarity
public override Stream Serialize(object source, Type objectType) { var ms = new MemoryStream(); - var writer = new StreamWriter(ms); + var writer = new StreamWriter(ms, Encoding.UTF8, leaveOpen: true); writer.Write(source?.ToString()); writer.Flush(); + writer.Dispose(); ms.Position = 0; return ms; }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@test/Codebelt.Extensions.Carter.Tests/Response/ConfigurableResponseNegotiatorTest.cs` around lines 134 - 142, In Serialize(object source, Type objectType) the StreamWriter wraps the MemoryStream without specifying leaveOpen, so make the intent explicit by creating the StreamWriter with leaveOpen: true (e.g., new StreamWriter(ms, /*encoding*/ null, /*bufferSize*/ 1024, leaveOpen: true)) before writing and flushing; this preserves the MemoryStream for return and clarifies ownership without changing the existing flush/return behavior in Serialize.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In @.docfx/BuildDocfxImage.ps1:
- Line 3: The docker build invocation in .docfx/BuildDocfxImage.ps1 uses --load
with multi-platform targets which is incompatible; update the docker buildx
command that references Dockerfile.docfx and the tag carter-docfx:$version to
either (A) build a single platform when using --load (e.g., remove the
multi-platform list and add --platform linux/amd64) for local development, or
(B) remove --load and add --push to publish the multi-platform image to a
registry; ensure the chosen change is applied to the docker buildx build line in
the script so the flags match the intended single- or multi-platform workflow.
In @.docfx/index.md:
- Around line 1-11: The image reference /images/128x128.png in .docfx/index.md
is missing; either add the 128x128.png asset into the .docfx/images/ directory
or update the markdown to point to an existing image (for example replace
/images/128x128.png with /images/50x50.png or /images/32x32.png), then commit
the added asset or the edited index.md so the frontpage image resolves
correctly.
In @.docfx/PublishDocfxImage.ps1:
- Around line 1-3: The script calls minver and blindly uses $version for docker
tag/push; add fail-fast and validation by setting $ErrorActionPreference =
'Stop' before invoking minver (or run minver with -ErrorAction Stop), wrap the
minver call in try/catch to capture failures, validate that $version is not
null/empty/whitespace (e.g., use [string]::IsNullOrWhiteSpace($version)), and if
validation fails call Write-Error/throw and exit with non-zero status; only
execute docker tag/push when $version is valid.
In @.editorconfig:
- Around line 24-28: The .editorconfig currently disables the entire Performance
analyzer category via the setting
dotnet_analyzer_diagnostic.category-Performance.severity = none; remove that
broad suppression and instead leave only explicit exceptions for the specific
rules unsupported by .NET Standard 2.0 (CA1846, CA1847, CA1865, CA1866, CA1867,
CA2249, CA2263) that already appear later in the file; update the config so
Performance category is not globally disabled for [*.{cs,vb}] and ensure only
the listed CA#### rule keys are set to none.
In @.github/CODE_OF_CONDUCT.md:
- Around line 65-67: Replace the placeholder token "[INSERT CONTACT METHOD]" in
the CODE_OF_CONDUCT.md text with a real, monitored contact (e.g., a project
email address or a URL to the incident/report form) so contributors have a valid
reporting channel; ensure the provided contact is actively monitored and
formatted clearly in the sentence that reads "reported to the community leaders
responsible for enforcement at [INSERT CONTACT METHOD]."
In @.github/workflows/scorecard.yml:
- Around line 21-40: The workflow currently pins actions with floating tags
(actions/checkout@v4, ossf/scorecard-action@v2.4.0, actions/upload-artifact@v4,
github/codeql-action/upload-sarif@v3); replace each uses: value with the
corresponding full 40-character commit SHA for that action (e.g.,
actions/checkout@<40-char-sha>) so no uses: lines match the regex for non-SHA
pins, verify each SHA is exact length and update results_file/upload steps
accordingly; keep the same action versions’ SHAs and rerun the regex shown in
the review to confirm zero matches.
In @.github/workflows/trigger-downstream.yml:
- Around line 57-74: Wrap each per-repo dispatch inside a try/except so one
failed dispatch doesn't abort the whole "for repo in targets" loop: call
urllib.request.urlopen(req, timeout=10) (or similar) instead of the current call
without timeout, catch urllib.error.HTTPError / urllib.error.URLError /
Exception around the urllib.request.urlopen invocation and log the repo name,
HTTP/status or error details, then continue to the next repo; keep the existing
Request construction (urllib.request.Request) but ensure the urlopen call uses
the timeout and is protected by the per-repo try/except.
In `@Directory.Build.targets`:
- Around line 13-14: The FileVersion uses GITHUB_RUN_NUMBER directly which can
exceed the 16-bit limit (0–65535); clamp the value before composing FileVersion.
Add a new property (e.g. ClampedGitHubRunNumber) that computes a safe integer
defaulting to 0 and using a property function to take the minimum of the numeric
GITHUB_RUN_NUMBER and 65535 (for example via System.Math::Min or
Convert.ToInt32/Parse as needed), then replace the fourth segment in the
FileVersion expression to use ClampedGitHubRunNumber instead of
GITHUB_RUN_NUMBER so the generated AssemblyFileVersion never exceeds 65535.
In `@src/Codebelt.Extensions.Carter/Response/ConfigurableResponseNegotiator.cs`:
- Around line 42-53: The CanHandle method mutates ContentType inside the LINQ
Any() predicate which creates side-effects and race conditions; change the logic
to first find a matching media type without mutation (e.g., use FirstOrDefault
or a simple loop over Options.SupportedMediaTypes and call
accept.MatchesMediaType(mediaType.MediaType)), then — outside the predicate —
set ContentType to the matched mediaType.MediaType if non-null and return
true/false accordingly; ensure you reference the CanHandle method,
Options.SupportedMediaTypes, ContentType, and MediaTypeHeaderValue accept when
making the change.
- Around line 116-127: The StreamWriter used in ConfigurableResponseNegotiator
(the block that creates "await using var textWriter = new StreamWriter(res.Body,
encoding);") will dispose the underlying res.Body when finalized; change the
constructor to pass the overload that sets leaveOpen: true (and optionally
bufferSize: -1) so the response stream is not closed when the writer is
disposed, ensuring subsequent middleware/response completion can still use
res.Body.
---
Minor comments:
In @.docfx/Dockerfile.docfx:
- Around line 3-4: The Dockerfile defines an unused build stage named "base"
(FROM ... AS base and its RUN) which is never referenced by any COPY --from= or
by the final stage that uses nginx:${NGINX_VERSION}; remove the dead "base"
stage to avoid confusion and reduce image complexity, or alternatively change
the final stage to use FROM base (and update any COPY --from= references) if the
intent was to seed the final image from that stage; locate the "base" stage
declaration and either delete those lines or update the final stage to reference
"base" accordingly.
In @.editorconfig:
- Around line 177-187: Remove the duplicated IDE0036 configuration block in
.editorconfig by keeping a single [*.{cs,vb}] section that sets
dotnet_diagnostic.IDE0036.severity = none and deleting the repeated duplicate;
ensure the remaining block includes the comment lines (Order modifiers and link)
and the single dotnet_diagnostic.IDE0036.severity entry so only one IDE0036
declaration exists.
- Around line 3-8: Add an .editorconfig override for Markdown files so
intentional hard line breaks aren't stripped: add a section for the glob [*.md]
that sets trim_trailing_whitespace = false (and optionally end_of_line and
insert_final_newline as desired) to override the global trim_trailing_whitespace
= true; update the file to include this [*.md] block so Markdown files preserve
trailing spaces while keeping the global rule for other files.
- Around line 105-113: Update the two comment lines that reference analyzer IDs
so they match the configured diagnostics: change the comment "IDE0039: Use
collection expression for array" to "IDE0300: Use collection expression for
array" and change "IDE0031: Use collection expression for empty" to "IDE0301:
Use collection expression for empty" so the comments align with the
dotnet_diagnostic IDE0300 and IDE0301 settings in the .editorconfig; locate the
comments adjacent to the blocks that configure
dotnet_diagnostic.IDE0300.severity = none and dotnet_diagnostic.IDE0301.severity
= none (the comment texts are the unique identifiers to edit).
In @.github/dependabot.yml:
- Around line 1-17: The file has CRLF line endings causing YAML lint failures;
convert .github/dependabot.yml to use LF (\n) line endings throughout (ensure
the top-level keys like "version: 2" and "updates:" and the package-ecosystem
entries remain unchanged) — update your editor or run a normalization (e.g.,
dos2unix or git config core.autocrlf=false then re-checkout) so the file is
saved with LF endings and re-run linting to confirm the error is resolved.
In @.github/workflows/ci-pipeline.yml:
- Around line 1-117: The YAML file "Carter CI Pipeline" has CRLF line endings
causing YAML lint failures; convert this workflow
(.github/workflows/ci-pipeline.yml) to use LF line endings, ensure the entire
file (including top-level fields like name, on, permissions and job blocks
build, pack, test_linux, test_windows, sonarcloud, codecov, codeql, deploy) is
normalized to LF, and add/commit the change (optionally add a .gitattributes
entry like "*.yml text eol=lf" to enforce LF for CI YAML files).
In @.github/workflows/service-update.yml:
- Around line 73-74: The ENTRY variable is passed directly to printf as a format
string (printf "$ENTRY"), which can misbehave if ENTRY contains percent signs;
update the write step to treat ENTRY as data rather than a format: change the
printf invocation that references ENTRY to use a safe form that expands
backslash escapes but does not treat percent signs as format specifiers (e.g.,
use printf '%b' with ENTRY or use echo -e), keeping the surrounding pipeline
that writes { printf ...; cat "$f"; } > "$f.tmp" && mv "$f.tmp" "$f" intact and
still referencing ENTRY and f.
In
@.nuget/Codebelt.Extensions.Carter.AspNetCore.Text.Yaml/PackageReleaseNotes.txt:
- Around line 3-6: Two blank lines in PackageReleaseNotes.txt contain
non-breaking spaces (NBSP) instead of true empty lines; open the file and remove
the U+00A0 characters on the affected blank lines so they become plain empty
lines (ensure lines reported around the "# New Features" section are just
newline characters), then save with normal whitespace/UTF-8 encoding so tools
render the blank lines correctly.
In @.nuget/Codebelt.Extensions.Carter.AspNetCore.Text.Yaml/README.md:
- Around line 19-31: The README sample references repository-internal symbols
(Codebelt.Extensions.Carter.Assets, WorldModule,
MinimalWebHostTestFactory.RunAsync) and an internal test-only module which will
break for NuGet consumers; replace those with a self-contained, public example:
remove usages of Codebelt.Extensions.Carter.Assets and WorldModule, substitute a
simple public Carter module (e.g., a public class MyPublicModule : Carter.Module
with a GET route) and a minimal host creation pattern instead of
MinimalWebHostTestFactory.RunAsync, and keep the relevant API calls shown
(services.AddMinimalYamlOptions(),
services.AddCarter(...).WithResponseNegotiator<YamlResponseNegotiator>()) so the
README demonstrates a copy/paste-able example using only public,
package-exported types.
In `@CHANGELOG.md`:
- Line 5: The sentence in CHANGELOG.md uses "per assembly basis" and should
hyphenate the compound adjective; change "on a per assembly basis" to "on a
per-assembly basis" so the phrase correctly uses the hyphenated modifier when
referring to `PackageReleaseNotes.txt` in the `.nuget` folder.
In `@README.md`:
- Around line 107-108: The package description string "Provides a focused API
for BenchmarkDotNet projects" is incorrect; replace that sentence in the README
(the package description line) with an accurate description for the Carter
negotiation extension packages, e.g. a short line stating these packages
"Provide Carter extensions for response content negotiation (media type
negotiation, formatters, and helpers)"; update only the offending sentence so it
clearly references Carter response negotiation rather than BenchmarkDotNet.
In
`@src/Codebelt.Extensions.Carter.AspNetCore.Newtonsoft.Json/NewtonsoftJsonNegotiator.cs`:
- Line 19: The constructor for NewtonsoftJsonNegotiator should guard the
incoming IOptions<NewtonsoftJsonFormatterOptions> parameter against null and
throw an ArgumentNullException rather than relying on base(options.Value) to
fail later; add an explicit null-check at the start of the
NewtonsoftJsonNegotiator(IOptions<NewtonsoftJsonFormatterOptions> options)
constructor and throw new ArgumentNullException(nameof(options)) if null, then
pass options.Value to the base constructor as before.
---
Nitpick comments:
In @.docfx/Dockerfile.docfx:
- Line 8: Replace the ADD instruction used to copy local files (the line
containing ADD [".", "docfx"]) with a COPY instruction so the Dockerfile uses
COPY [".", "docfx"] instead of ADD; this removes unnecessary ADD behavior (tar
extraction/URL fetch) and follows Docker best practices for copying local files.
In @.docfx/filterConfig.yml:
- Around line 1-4: The YAML file defining apiRules (contains keys like apiRules,
exclude, uidRegex: ^System\.Object and type: Type) uses Windows CRLF line
endings; convert the file to Unix-style LF line endings (e.g., via your editor
“save with LF”, dos2unix, or git config core.autocrlf=false) and commit the
normalized file so YAML linting passes; optionally add or update .gitattributes
to enforce LF for .yml files to prevent future CRLFs.
In @.docfx/toc.yml:
- Around line 1-4: The .docfx/toc.yml file (containing entries "Carter API" and
"NuGet") has CRLF line endings which fail YAMLlint; convert this file to use
Unix LF line endings, commit the normalized file, and ensure your editor/IDE is
set to save .yml files with LF; additionally add a repository-wide rule (e.g. a
.gitattributes entry forcing eol=lf for *.yml) so future commits preserve LF
across CI and developer machines.
In @.github/codecov.yml:
- Around line 1-2: Update the ignore pattern under the ignore key to a more
precise glob such as "test/**" or "**/test/**" instead of "test" to avoid
matching unintended paths, and normalize the file's line endings to LF (fix the
same newline character issue flagged by yamllint); after making these changes
run a YAML linter/validator to confirm the YAML is valid and the newline issue
is resolved.
In @.github/CONTRIBUTING.md:
- Around line 19-21: Update the PR checklist wording in .github/CONTRIBUTING.md
(the bullet items that currently read "Any changes or additions requires
documentation in the form of documenting public members", "Ensure that all
existing as well as new test passes", and "Issue that pull request with a big
and heartful thanks for contributing") to correct grammar and word choice:
change "requires" to "require", change "test passes" to "tests pass", and
replace "heartful" with "heartfelt" (or "warm") and adjust surrounding phrasing
so each checklist item reads clearly and grammatically correct.
In @.github/copilot-instructions.md:
- Around line 300-301: The XML documentation example incorrectly uses an
external namespace (namespace Cuemon.Security); update the example to use a
project-specific namespace (e.g., namespace Codebelt.Extensions.Carter.Security
or the consistent Codebelt.Extensions.Carter.* pattern used in the repo) so it
aligns with other examples; locate the namespace declaration in the example
block (the line containing "namespace Cuemon.Security") and replace it with the
appropriate Codebelt.Extensions.Carter.* namespace while keeping the rest of the
XML documentation example unchanged.
In @.github/scripts/bump-nuget.py:
- Line 130: The return statement uses a redundant conditional expression in
bump_nuget.py: replace the unnecessary ternary "return 0 if changes else 0" with
a simple "return 0" to eliminate the dead conditional; locate the return inside
the function handling changes (the same scope that currently uses the variable
changes) and simplify it to a single unconditional return value.
In
`@src/Codebelt.Extensions.Carter.AspNetCore.Text.Yaml/Codebelt.Extensions.Carter.AspNetCore.Text.Yaml.csproj`:
- Line 5: The PackageTags element in
Codebelt.Extensions.Carter.AspNetCore.Text.Yaml.csproj is missing the "codebelt"
tag; update the <PackageTags> value (the PackageTags XML element) to include
"codebelt" alongside the existing tags (e.g., add it to "extension-methods
extensions carter response-negotiation yaml yamldotnet asp-net-core
minimal-api") so the package tag list matches the other Text.* extension
projects for consistency and discoverability.
In `@src/Codebelt.Extensions.Carter.AspNetCore.Xml/XmlResponseNegotiator.cs`:
- Line 13: Remove the extra leading indentation before the class declaration so
the "public class XmlResponseNegotiator :
ConfigurableResponseNegotiator<XmlFormatterOptions>" line aligns with the
surrounding namespace block style; locate the XmlResponseNegotiator class
declaration and adjust its indentation to match the file's namespace/class
formatting convention.
In
`@test/Codebelt.Extensions.Carter.AspNetCore.Newtonsoft.Json.Tests/NewtonsoftJsonNegotiatorTest.cs`:
- Around line 94-98: The FakeModel.Name property is declared as non-nullable
string but has no initializer, so mark it explicitly nullable or give it a
default to avoid possible nulls at runtime; update the FakeModel class by
changing the Name property's type to string? (nullable) or initialize it (e.g.,
Name = string.Empty) so serializers won't encounter an uninitialized null—refer
to FakeModel and the Name property when making the change.
In `@test/Codebelt.Extensions.Carter.FunctionalTests/Assets/WorldModule.cs`:
- Around line 17-19: The response currently projects World.StatisticalRegions
into StatisticalRegionModel and negotiates it via res.Negotiate but does not
enforce a deterministic ordering; to fix, sort the sequence before projection
(e.g., OrderBy on a stable key such as r.Code or r.Name) so that the enumerable
passed to res.Negotiate is consistently ordered; update the LINQ pipeline around
World.StatisticalRegions.Where(...).Select(...) to include an OrderBy (or
ThenBy) before Select to guarantee stable ordering in the returned
StatisticalRegionModel sequence.
In
`@test/Codebelt.Extensions.Carter.FunctionalTests/Codebelt.Extensions.Carter.FunctionalTests.csproj`:
- Around line 8-10: Remove the stale exclusion entries referencing the
non-existent NewFolder by deleting the three project lines containing Compile
Remove="NewFolder\**", EmbeddedResource Remove="NewFolder\**" and None
Remove="NewFolder\**" from the .csproj so the file no longer contains those
obsolete rules.
In
`@test/Codebelt.Extensions.Carter.Tests/Response/ConfigurableResponseNegotiatorTest.cs`:
- Around line 134-142: In Serialize(object source, Type objectType) the
StreamWriter wraps the MemoryStream without specifying leaveOpen, so make the
intent explicit by creating the StreamWriter with leaveOpen: true (e.g., new
StreamWriter(ms, /*encoding*/ null, /*bufferSize*/ 1024, leaveOpen: true))
before writing and flushing; this preserves the MemoryStream for return and
clarifies ownership without changing the existing flush/return behavior in
Serialize.
In `@testenvironments.json`:
- Line 1: Add a top-level "$schema" property to the JSON document (in
testenvironments.json) so IDEs can validate and offer autocomplete; modify the
root object creation (where the file currently begins with "{") to include a
"$schema" key whose value points to the appropriate JSON Schema URI (for example
a local or standard schema for your test env format) so editors can pick up
validation and suggestions.
- Line 7: The WSL distribution "Ubuntu-24.04" referenced by the wslDistribution
setting may not exist on all developer machines; update project docs and/or CI
docs to state this requirement and add an installation or fallback instruction:
document that the testenvironments.json key "wslDistribution" must be installed,
include the exact distribution name ("Ubuntu-24.04") and provide step-by-step
WSL install commands (or recommend an alternative distribution and how to change
the wslDistribution value) so team members can reproduce the test environment
reliably.
- Line 12: The docker image is already version-pinned under the "dockerImage"
key with value "codebeltnet/ubuntu-testrunner:net8.0.418-9.0.311-10.0.103" which
is correct for reproducible tests; no change required now—keep the exact tag but
add a periodic reminder or task to update these .NET version tags (for example
in your release/maintenance checklist) so the "dockerImage" value is reviewed
and updated when new .NET patch or major releases are adopted.
ℹ️ Review info
Configuration used: defaults
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (8)
.docfx/images/32x32.pngis excluded by!**/*.png.docfx/images/50x50.pngis excluded by!**/*.png.docfx/images/favicon.icois excluded by!**/*.ico.nuget/Codebelt.Extensions.Carter.AspNetCore.Newtonsoft.Json/icon.pngis excluded by!**/*.png.nuget/Codebelt.Extensions.Carter.AspNetCore.Text.Json/icon.pngis excluded by!**/*.png.nuget/Codebelt.Extensions.Carter.AspNetCore.Text.Yaml/icon.pngis excluded by!**/*.png.nuget/Codebelt.Extensions.Carter.AspNetCore.Xml/icon.pngis excluded by!**/*.png.nuget/Codebelt.Extensions.Carter/icon.pngis excluded by!**/*.png
📒 Files selected for processing (72)
.docfx/BuildDocfxImage.ps1.docfx/Dockerfile.docfx.docfx/PublishDocfxImage.ps1.docfx/api/namespaces/Codebelt.Extensions.Carter.AspNetCore.Newtonsoft.Json.md.docfx/api/namespaces/Codebelt.Extensions.Carter.AspNetCore.Text.Json.md.docfx/api/namespaces/Codebelt.Extensions.Carter.AspNetCore.Text.Yaml.md.docfx/api/namespaces/Codebelt.Extensions.Carter.AspNetCore.Xml.md.docfx/api/namespaces/Codebelt.Extensions.Carter.md.docfx/docfx.json.docfx/filterConfig.yml.docfx/includes/availability-modern.md.docfx/index.md.docfx/toc.yml.editorconfig.github/CODE_OF_CONDUCT.md.github/CONTRIBUTING.md.github/codecov.yml.github/copilot-instructions.md.github/dependabot.yml.github/dispatch-targets.json.github/scripts/bump-nuget.py.github/workflows/ci-pipeline.yml.github/workflows/scorecard.yml.github/workflows/service-update.yml.github/workflows/trigger-downstream.yml.gitignore.nuget/Codebelt.Extensions.Carter.AspNetCore.Newtonsoft.Json/PackageReleaseNotes.txt.nuget/Codebelt.Extensions.Carter.AspNetCore.Newtonsoft.Json/README.md.nuget/Codebelt.Extensions.Carter.AspNetCore.Text.Json/PackageReleaseNotes.txt.nuget/Codebelt.Extensions.Carter.AspNetCore.Text.Json/README.md.nuget/Codebelt.Extensions.Carter.AspNetCore.Text.Yaml/PackageReleaseNotes.txt.nuget/Codebelt.Extensions.Carter.AspNetCore.Text.Yaml/README.md.nuget/Codebelt.Extensions.Carter.AspNetCore.Xml/PackageReleaseNotes.txt.nuget/Codebelt.Extensions.Carter.AspNetCore.Xml/README.md.nuget/Codebelt.Extensions.Carter/PackageReleaseNotes.txt.nuget/Codebelt.Extensions.Carter/README.mdCHANGELOG.mdCodebelt.Extensions.Carter.slnxDirectory.Build.propsDirectory.Build.targetsDirectory.Packages.propsLICENSEREADME.mdsrc/Codebelt.Extensions.Carter.AspNetCore.Newtonsoft.Json/Codebelt.Extensions.Carter.AspNetCore.Newtonsoft.Json.csprojsrc/Codebelt.Extensions.Carter.AspNetCore.Newtonsoft.Json/NewtonsoftJsonNegotiator.cssrc/Codebelt.Extensions.Carter.AspNetCore.Text.Json/Codebelt.Extensions.Carter.AspNetCore.Text.Json.csprojsrc/Codebelt.Extensions.Carter.AspNetCore.Text.Json/JsonResponseNegotiator.cssrc/Codebelt.Extensions.Carter.AspNetCore.Text.Yaml/Codebelt.Extensions.Carter.AspNetCore.Text.Yaml.csprojsrc/Codebelt.Extensions.Carter.AspNetCore.Text.Yaml/YamlResponseNegotiator.cssrc/Codebelt.Extensions.Carter.AspNetCore.Xml/Codebelt.Extensions.Carter.AspNetCore.Xml.csprojsrc/Codebelt.Extensions.Carter.AspNetCore.Xml/XmlResponseNegotiator.cssrc/Codebelt.Extensions.Carter/Codebelt.Extensions.Carter.csprojsrc/Codebelt.Extensions.Carter/EndpointConventionBuilderExtensions.cssrc/Codebelt.Extensions.Carter/Response/ConfigurableResponseNegotiator.cstest/Codebelt.Extensions.Carter.AspNetCore.Newtonsoft.Json.Tests/Codebelt.Extensions.Carter.AspNetCore.Newtonsoft.Json.Tests.csprojtest/Codebelt.Extensions.Carter.AspNetCore.Newtonsoft.Json.Tests/NewtonsoftJsonNegotiatorTest.cstest/Codebelt.Extensions.Carter.AspNetCore.Text.Json.Tests/Codebelt.Extensions.Carter.AspNetCore.Text.Json.Tests.csprojtest/Codebelt.Extensions.Carter.AspNetCore.Text.Json.Tests/JsonResponseNegotiatorTest.cstest/Codebelt.Extensions.Carter.AspNetCore.Text.Yaml.Tests/Codebelt.Extensions.Carter.AspNetCore.Text.Yaml.Tests.csprojtest/Codebelt.Extensions.Carter.AspNetCore.Text.Yaml.Tests/YamlResponseNegotiatorTest.cstest/Codebelt.Extensions.Carter.AspNetCore.Xml.Tests/Codebelt.Extensions.Carter.AspNetCore.Xml.Tests.csprojtest/Codebelt.Extensions.Carter.AspNetCore.Xml.Tests/XmlResponseNegotiatorTest.cstest/Codebelt.Extensions.Carter.FunctionalTests/Assets/WorldModule.cstest/Codebelt.Extensions.Carter.FunctionalTests/Codebelt.Extensions.Carter.FunctionalTests.csprojtest/Codebelt.Extensions.Carter.FunctionalTests/JsonResponseNegotiatorTest.cstest/Codebelt.Extensions.Carter.FunctionalTests/NewtonsoftJsonNegotiatorTest.cstest/Codebelt.Extensions.Carter.FunctionalTests/XmlResponseNegotiatorTest.cstest/Codebelt.Extensions.Carter.FunctionalTests/YamlResponseNegotiatorTest.cstest/Codebelt.Extensions.Carter.Tests/Codebelt.Extensions.Carter.Tests.csprojtest/Codebelt.Extensions.Carter.Tests/EndpointConventionBuilderExtensionsTest.cstest/Codebelt.Extensions.Carter.Tests/Response/ConfigurableResponseNegotiatorTest.cstestenvironments.json
| @@ -0,0 +1,4 @@ | |||
| $version = minver -i -t v -v w | |||
| docfx metadata docfx.json | |||
| docker buildx build -t carter-docfx:$version --platform linux/arm64,linux/amd64 --load -f Dockerfile.docfx . | |||
There was a problem hiding this comment.
--load incompatible with multi-platform builds.
The --load flag loads the built image into the local Docker daemon, but this only works for single-platform images. When building for multiple platforms (linux/arm64,linux/amd64), Docker cannot load multi-arch images locally. The build will either fail or only load one platform.
Consider either:
- Build for a single platform when loading locally
- Use
--pushto push multi-platform images to a registry
Proposed fix for local development (single platform)
-docker buildx build -t carter-docfx:$version --platform linux/arm64,linux/amd64 --load -f Dockerfile.docfx .
+docker buildx build -t carter-docfx:$version --platform linux/amd64 --load -f Dockerfile.docfx .Or for multi-platform with registry push:
-docker buildx build -t carter-docfx:$version --platform linux/arm64,linux/amd64 --load -f Dockerfile.docfx .
+docker buildx build -t carter-docfx:$version --platform linux/arm64,linux/amd64 --push -f Dockerfile.docfx .📝 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.
| docker buildx build -t carter-docfx:$version --platform linux/arm64,linux/amd64 --load -f Dockerfile.docfx . | |
| docker buildx build -t carter-docfx:$version --platform linux/amd64 --load -f Dockerfile.docfx . |
| docker buildx build -t carter-docfx:$version --platform linux/arm64,linux/amd64 --load -f Dockerfile.docfx . | |
| docker buildx build -t carter-docfx:$version --platform linux/arm64,linux/amd64 --push -f Dockerfile.docfx . |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In @.docfx/BuildDocfxImage.ps1 at line 3, The docker build invocation in
.docfx/BuildDocfxImage.ps1 uses --load with multi-platform targets which is
incompatible; update the docker buildx command that references Dockerfile.docfx
and the tag carter-docfx:$version to either (A) build a single platform when
using --load (e.g., remove the multi-platform list and add --platform
linux/amd64) for local development, or (B) remove --load and add --push to
publish the multi-platform image to a registry; ensure the chosen change is
applied to the docker buildx build line in the script so the flags match the
intended single- or multi-platform workflow.
| $version = minver -i -t v -v w | ||
| docker tag carter-docfx:$version jcr.codebelt.net/geekle/carter-docfx:$version | ||
| docker push jcr.codebelt.net/geekle/carter-docfx:$version |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
# Verify the current state of the PowerShell script
rg -n "ErrorActionPreference|Set-StrictMode|Get-Command minver|IsNullOrWhiteSpace|throw" .docfx/PublishDocfxImage.ps1 || echo "No guard patterns found"Repository: codebeltnet/carter
Length of output: 85
🏁 Script executed:
# Also read the full file to understand its current state
cat -n .docfx/PublishDocfxImage.ps1Repository: codebeltnet/carter
Length of output: 252
Add fail-fast and version validation before tagging and pushing.
The script lacks error handling: if minver fails or returns an empty value, Lines 2–3 will execute with an invalid tag. Add strict error handling and validate $version before use.
🛠️ Proposed hardening
+$ErrorActionPreference = 'Stop'
+Set-StrictMode -Version Latest
+
+$minver = Get-Command minver -ErrorAction SilentlyContinue
+if (-not $minver) { throw "minver CLI is required but was not found in PATH." }
+
$version = minver -i -t v -v w
+if ([string]::IsNullOrWhiteSpace($version)) { throw "Resolved version is empty." }
+
docker tag carter-docfx:$version jcr.codebelt.net/geekle/carter-docfx:$version
docker push jcr.codebelt.net/geekle/carter-docfx:$version📝 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.
| $version = minver -i -t v -v w | |
| docker tag carter-docfx:$version jcr.codebelt.net/geekle/carter-docfx:$version | |
| docker push jcr.codebelt.net/geekle/carter-docfx:$version | |
| $ErrorActionPreference = 'Stop' | |
| Set-StrictMode -Version Latest | |
| $minver = Get-Command minver -ErrorAction SilentlyContinue | |
| if (-not $minver) { throw "minver CLI is required but was not found in PATH." } | |
| $version = minver -i -t v -v w | |
| if ([string]::IsNullOrWhiteSpace($version)) { throw "Resolved version is empty." } | |
| docker tag carter-docfx:$version jcr.codebelt.net/geekle/carter-docfx:$version | |
| docker push jcr.codebelt.net/geekle/carter-docfx:$version |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In @.docfx/PublishDocfxImage.ps1 around lines 1 - 3, The script calls minver and
blindly uses $version for docker tag/push; add fail-fast and validation by
setting $ErrorActionPreference = 'Stop' before invoking minver (or run minver
with -ErrorAction Stop), wrap the minver call in try/catch to capture failures,
validate that $version is not null/empty/whitespace (e.g., use
[string]::IsNullOrWhiteSpace($version)), and if validation fails call
Write-Error/throw and exit with non-zero status; only execute docker tag/push
when $version is valid.
| # Performance rules | ||
| # https://docs.microsoft.com/da-dk/dotnet/fundamentals/code-analysis/quality-rules/performance-warnings | ||
| [*.{cs,vb}] | ||
| dotnet_analyzer_diagnostic.category-Performance.severity = none # Because many of the suggestions by performance analyzers are not compatible with .NET Standard 2.0 | ||
|
|
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
cat -n .editorconfigRepository: codebeltnet/carter
Length of output: 9405
Narrow broad performance suppression scope.
Line 27 disables the entire Performance category for all C#/VB files, which suppresses useful findings on modern TFMs. Remove this broad suppression and keep only the specific rules already listed below that are genuinely unsupported for .NET Standard 2.0: CA1846, CA1847, CA1865–CA1867, CA2249, and CA2263 (lines 135–165).
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In @.editorconfig around lines 24 - 28, The .editorconfig currently disables the
entire Performance analyzer category via the setting
dotnet_analyzer_diagnostic.category-Performance.severity = none; remove that
broad suppression and instead leave only explicit exceptions for the specific
rules unsupported by .NET Standard 2.0 (CA1846, CA1847, CA1865, CA1866, CA1867,
CA2249, CA2263) that already appear later in the file; update the config so
Performance category is not globally disabled for [*.{cs,vb}] and ensure only
the listed CA#### rule keys are set to none.
| reported to the community leaders responsible for enforcement at | ||
| [INSERT CONTACT METHOD]. | ||
| All complaints will be reviewed and investigated promptly and fairly. |
There was a problem hiding this comment.
Replace enforcement contact placeholder before merge.
Line 66 still contains [INSERT CONTACT METHOD]. This leaves contributors without a real reporting channel for Code of Conduct incidents, which undermines enforceability.
Suggested fix
-reported to the community leaders responsible for enforcement at
-[INSERT CONTACT METHOD].
+reported to the community leaders responsible for enforcement at
+[conduct@codebelt.net](mailto:conduct@codebelt.net).(Use your actual monitored alias/form URL.)
📝 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.
| reported to the community leaders responsible for enforcement at | |
| [INSERT CONTACT METHOD]. | |
| All complaints will be reviewed and investigated promptly and fairly. | |
| reported to the community leaders responsible for enforcement at | |
| [conduct@codebelt.net](mailto:conduct@codebelt.net). | |
| All complaints will be reviewed and investigated promptly and fairly. |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In @.github/CODE_OF_CONDUCT.md around lines 65 - 67, Replace the placeholder
token "[INSERT CONTACT METHOD]" in the CODE_OF_CONDUCT.md text with a real,
monitored contact (e.g., a project email address or a URL to the incident/report
form) so contributors have a valid reporting channel; ensure the provided
contact is actively monitored and formatted clearly in the sentence that reads
"reported to the community leaders responsible for enforcement at [INSERT
CONTACT METHOD]."
| uses: actions/checkout@v4 | ||
| with: | ||
| persist-credentials: false | ||
|
|
||
| - name: "Run analysis" | ||
| uses: ossf/scorecard-action@v2.4.0 | ||
| with: | ||
| results_file: results.sarif | ||
| results_format: sarif | ||
| publish_results: true | ||
|
|
||
| - name: "Upload artifact" | ||
| uses: actions/upload-artifact@v4 | ||
| with: | ||
| name: SARIF file | ||
| path: results.sarif | ||
| retention-days: 5 | ||
|
|
||
| - name: "Upload to code-scanning" | ||
| uses: github/codeql-action/upload-sarif@v3 |
There was a problem hiding this comment.
Pin GitHub Actions to immutable commit SHAs.
Lines 21, 26, 33, and 40 use floating tags (@v*). For a supply-chain security workflow, pin each action to a full commit SHA.
🔐 Pinning pattern (example)
- - name: "Checkout code"
- uses: actions/checkout@v4
+ - name: "Checkout code"
+ uses: actions/checkout@<40-char-commit-sha> # v4
- - name: "Run analysis"
- uses: ossf/scorecard-action@v2.4.0
+ - name: "Run analysis"
+ uses: ossf/scorecard-action@<40-char-commit-sha> # v2.4.0
- - name: "Upload artifact"
- uses: actions/upload-artifact@v4
+ - name: "Upload artifact"
+ uses: actions/upload-artifact@<40-char-commit-sha> # v4
- - name: "Upload to code-scanning"
- uses: github/codeql-action/upload-sarif@v3
+ - name: "Upload to code-scanning"
+ uses: github/codeql-action/upload-sarif@<40-char-commit-sha> # v3#!/bin/bash
# Find workflow action references not pinned to a full 40-char SHA.
rg -nP '^\s*uses:\s*[^@\s]+@(?![0-9a-fA-F]{40}\b)\S+' .github/workflows/scorecard.ymlExpected result after fix: no matches.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In @.github/workflows/scorecard.yml around lines 21 - 40, The workflow currently
pins actions with floating tags (actions/checkout@v4,
ossf/scorecard-action@v2.4.0, actions/upload-artifact@v4,
github/codeql-action/upload-sarif@v3); replace each uses: value with the
corresponding full 40-character commit SHA for that action (e.g.,
actions/checkout@<40-char-sha>) so no uses: lines match the regex for non-SHA
pins, verify each SHA is exact length and update results_file/upload steps
accordingly; keep the same action versions’ SHAs and rerun the regex shown in
the review to confirm zero matches.
| for repo in targets: | ||
| url = f'https://api.github.com/repos/codebeltnet/{repo}/dispatches' | ||
| payload = json.dumps({ | ||
| 'event_type': 'codebelt-service-update', | ||
| 'client_payload': { | ||
| 'source_repo': source, | ||
| 'source_version': version | ||
| } | ||
| }).encode() | ||
| req = urllib.request.Request(url, data=payload, method='POST', headers={ | ||
| 'Authorization': f'Bearer {token}', | ||
| 'Accept': 'application/vnd.github+json', | ||
| 'Content-Type': 'application/json', | ||
| 'X-GitHub-Api-Version': '2022-11-28' | ||
| }) | ||
| with urllib.request.urlopen(req) as r: | ||
| print(f'✓ Dispatched to {repo}: HTTP {r.status}') | ||
| EOF |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
rg -n 'urlopen\(req\)|timeout=|try:|except' .github/workflows/trigger-downstream.yml -C2Repository: codebeltnet/carter
Length of output: 283
🏁 Script executed:
sed -n '57,74p' .github/workflows/trigger-downstream.ymlRepository: codebeltnet/carter
Length of output: 926
Harden downstream fan-out to avoid single-point failure in dispatch loop.
One failed dispatch currently stops all remaining dispatches, and the outbound call has no timeout. This makes release propagation brittle.
🔧 Proposed fix
- for repo in targets:
+ failures = []
+ for repo in targets:
url = f'https://api.github.com/repos/codebeltnet/{repo}/dispatches'
payload = json.dumps({
'event_type': 'codebelt-service-update',
'client_payload': {
'source_repo': source,
'source_version': version
}
}).encode()
req = urllib.request.Request(url, data=payload, method='POST', headers={
'Authorization': f'Bearer {token}',
'Accept': 'application/vnd.github+json',
'Content-Type': 'application/json',
'X-GitHub-Api-Version': '2022-11-28'
})
- with urllib.request.urlopen(req) as r:
- print(f'✓ Dispatched to {repo}: HTTP {r.status}')
+ try:
+ with urllib.request.urlopen(req, timeout=15) as r:
+ print(f'✓ Dispatched to {repo}: HTTP {r.status}')
+ except Exception as ex:
+ failures.append((repo, str(ex)))
+ print(f'✗ Failed dispatch to {repo}: {ex}', file=sys.stderr)
+
+ if failures:
+ raise SystemExit(
+ f"Dispatch failed for {len(failures)} repo(s): "
+ + ", ".join(repo for repo, _ in failures)
+ )🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In @.github/workflows/trigger-downstream.yml around lines 57 - 74, Wrap each
per-repo dispatch inside a try/except so one failed dispatch doesn't abort the
whole "for repo in targets" loop: call urllib.request.urlopen(req, timeout=10)
(or similar) instead of the current call without timeout, catch
urllib.error.HTTPError / urllib.error.URLError / Exception around the
urllib.request.urlopen invocation and log the repo name, HTTP/status or error
details, then continue to the next repo; keep the existing Request construction
(urllib.request.Request) but ensure the urlopen call uses the timeout and is
protected by the per-repo try/except.
| <GITHUB_RUN_NUMBER Condition="'$(GITHUB_RUN_NUMBER)' == ''">0</GITHUB_RUN_NUMBER> | ||
| <FileVersion>$(MinVerMajor).$(MinVerMinor).$(MinVerPatch).$(GITHUB_RUN_NUMBER)</FileVersion> |
There was a problem hiding this comment.
🧩 Analysis chain
🌐 Web query:
.NET System.Version component numeric limit maximum value 65535 AssemblyFileVersion
💡 Result:
System.Versionitself storesMajor/Minor/Build/Revisionas 32-bit integers (so the type doesn’t inherently cap you at 65,535), and it mainly defines the shapemajor.minor[.build[.revision]]. [1]- Assembly identity version (
[assembly: AssemblyVersion("…")]) is limited by CLR metadata: each of the 4 components must be 0–65534 (UInt16.MaxValue - 1). If you use 65535, the C# compiler rejects it. [3] - Win32 file version resource (
[assembly: AssemblyFileVersion("…")]) maps to Windows’ VERSIONINFO/FILEVERSION format (four 16-bit “words”), so each component can be 0–65535. Tools that consume the Win32 file version commonly document 65,535 as the per-field max. [4][5] - Microsoft’s guidance also distinguishes the intent:
AssemblyVersionis for binding/loading, whileAssemblyFileVersionis what Explorer shows and isn’t used by the CLR for binding. [2]
So: if you’re hitting the “65535” edge, it’s usually because you’re setting AssemblyVersion (max 65534), not AssemblyFileVersion (max 65535). [3][4]
🌐 Web query:
MSBuild FileVersion property AssemblyFileVersion vs AssemblyVersion what limit
💡 Result:
AssemblyVersion(→AssemblyVersionAttribute): The CLR/loader version used for assembly identity and (especially) strong-name binding policy decisions. Keep this relatively stable unless you intend to force binding changes. [1]FileVersion(→AssemblyFileVersionAttribute): The Win32 “file version” shown in Windows file properties; not used by the .NET runtime for binding. Safe to change every build. [1]
Where AssemblyFileVersion fits (MSBuild property):
- In SDK-style .csproj, the Microsoft.NET.Sdk uses
FileVersionto generateAssemblyFileVersionAttribute;AssemblyVersionandFileVersiondefault from$(Version)(with any prerelease suffix removed). [2] - The MSBuild property name
AssemblyFileVersionis commonly used by external versioning tooling (and some older build tasks) as an alias feeding the same concept asFileVersion/AssemblyFileVersionAttribute. Example tools set bothAssemblyFileVersionandFileVersion. [3]
Version-number limits (the “what limit” part):
AssemblyVersionandAssemblyFileVersionmust be 2–4 dot-separated integers (no letters/suffixes). [4]- Each numeric component is effectively limited to 16-bit; in practice you’ll hit errors above 65534 (often described as
UInt16.MaxValue - 1). This is why schemes likeYYYYMMDDcan break. [4][5]
If you need SemVer/prerelease labels/commit IDs:
- Put those in
InformationalVersion(→AssemblyInformationalVersionAttribute), which defaults to$(Version)and can include suffix/metadata. [2][4]
Sources:
[1] Microsoft Learn (Troubleshoot): “Use AssemblyVersion and AssemblyFileVersion” [1] (learn.microsoft.com)
[2] Microsoft Learn: “Set assembly attributes in a project file” (defaults and mapping from $(Version)) (learn.microsoft.com)
[3] Nerdbank.GitVersioning MSBuild docs (shows AssemblyFileVersion and FileVersion both used) (dotnet.github.io)
[4] Stack Overflow: format + 65534-per-component limit; use AssemblyInformationalVersion for strings (stackoverflow.com)
[5] Microsoft DevBlogs (Buck Hodges): version parts stored as 16-bit; “Y2K7” issue (devblogs.microsoft.com)
Citations:
- 1: https://learn.microsoft.com/en-us/troubleshoot/developer/dotnet/framework/general/assembly-version-assembly-file-version?utm_source=openai
- 2: https://learn.microsoft.com/en-us/dotnet/standard/assembly/set-attributes-project-file?utm_source=openai
- 3: https://dotnet.github.io/Nerdbank.GitVersioning/docs/build-systems/msbuild.html?utm_source=openai
- 4: https://stackoverflow.com/questions/11489917/msbuild-custom-assembly-version-format?utm_source=openai
- 5: https://devblogs.microsoft.com/buckh/how-to-deal-with-the-y2k7-problem-file-versions-and-assemblyinfotask/?utm_source=openai
FileVersion component has a 16-bit limit that can be exceeded by unbounded CI run numbers.
The fourth version segment of AssemblyFileVersion (FileVersion in MSBuild) is limited to 0–65535 as a 16-bit word in the Win32 VERSIONINFO structure. GitHub's GITHUB_RUN_NUMBER increments indefinitely, so it will eventually exceed this limit and cause build failures. Clamp the value to prevent invalid versions.
🐛 Proposed fix
<Target Name="ApplyFileVersion" AfterTargets="MinVer">
<PropertyGroup>
<GITHUB_RUN_NUMBER Condition="'$(GITHUB_RUN_NUMBER)' == ''">0</GITHUB_RUN_NUMBER>
- <FileVersion>$(MinVerMajor).$(MinVerMinor).$(MinVerPatch).$(GITHUB_RUN_NUMBER)</FileVersion>
+ <GITHUB_RUN_NUMBER_SAFE>$([System.Math]::Min(65535, $([System.Int32]::Parse('$(GITHUB_RUN_NUMBER)'))))</GITHUB_RUN_NUMBER_SAFE>
+ <FileVersion>$(MinVerMajor).$(MinVerMinor).$(MinVerPatch).$(GITHUB_RUN_NUMBER_SAFE)</FileVersion>
</PropertyGroup>
</Target>📝 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.
| <GITHUB_RUN_NUMBER Condition="'$(GITHUB_RUN_NUMBER)' == ''">0</GITHUB_RUN_NUMBER> | |
| <FileVersion>$(MinVerMajor).$(MinVerMinor).$(MinVerPatch).$(GITHUB_RUN_NUMBER)</FileVersion> | |
| <GITHUB_RUN_NUMBER Condition="'$(GITHUB_RUN_NUMBER)' == ''">0</GITHUB_RUN_NUMBER> | |
| <GITHUB_RUN_NUMBER_SAFE>$([System.Math]::Min(65535, $([System.Int32]::Parse('$(GITHUB_RUN_NUMBER)'))))</GITHUB_RUN_NUMBER_SAFE> | |
| <FileVersion>$(MinVerMajor).$(MinVerMinor).$(MinVerPatch).$(GITHUB_RUN_NUMBER_SAFE)</FileVersion> |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@Directory.Build.targets` around lines 13 - 14, The FileVersion uses
GITHUB_RUN_NUMBER directly which can exceed the 16-bit limit (0–65535); clamp
the value before composing FileVersion. Add a new property (e.g.
ClampedGitHubRunNumber) that computes a safe integer defaulting to 0 and using a
property function to take the minimum of the numeric GITHUB_RUN_NUMBER and 65535
(for example via System.Math::Min or Convert.ToInt32/Parse as needed), then
replace the fourth segment in the FileVersion expression to use
ClampedGitHubRunNumber instead of GITHUB_RUN_NUMBER so the generated
AssemblyFileVersion never exceeds 65535.
| public virtual bool CanHandle(MediaTypeHeaderValue accept) | ||
| { | ||
| return Options.SupportedMediaTypes.Any(mediaType => | ||
| { | ||
| if (accept.MatchesMediaType(mediaType.MediaType)) | ||
| { | ||
| ContentType = mediaType.MediaType; | ||
| return true; | ||
| } | ||
| return false; | ||
| }); | ||
| } |
There was a problem hiding this comment.
Side-effect in LINQ predicate could cause issues with concurrent access.
The CanHandle method mutates ContentType inside the LINQ Any() predicate. This pattern is problematic because:
- If called from multiple threads, race conditions could occur on
ContentType. - The mutation depends on evaluation order, which could be unexpected.
Consider extracting the matching logic to avoid side-effects in the predicate.
♻️ Proposed refactor
public virtual bool CanHandle(MediaTypeHeaderValue accept)
{
- return Options.SupportedMediaTypes.Any(mediaType =>
+ var matchedMediaType = Options.SupportedMediaTypes.FirstOrDefault(mediaType =>
+ accept.MatchesMediaType(mediaType.MediaType));
+
+ if (matchedMediaType is not null)
{
- if (accept.MatchesMediaType(mediaType.MediaType))
- {
- ContentType = mediaType.MediaType;
- return true;
- }
- return false;
- });
+ ContentType = matchedMediaType.MediaType;
+ return true;
+ }
+ return false;
}📝 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.
| public virtual bool CanHandle(MediaTypeHeaderValue accept) | |
| { | |
| return Options.SupportedMediaTypes.Any(mediaType => | |
| { | |
| if (accept.MatchesMediaType(mediaType.MediaType)) | |
| { | |
| ContentType = mediaType.MediaType; | |
| return true; | |
| } | |
| return false; | |
| }); | |
| } | |
| public virtual bool CanHandle(MediaTypeHeaderValue accept) | |
| { | |
| var matchedMediaType = Options.SupportedMediaTypes.FirstOrDefault(mediaType => | |
| accept.MatchesMediaType(mediaType.MediaType)); | |
| if (matchedMediaType is not null) | |
| { | |
| ContentType = matchedMediaType.MediaType; | |
| return true; | |
| } | |
| return false; | |
| } |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/Codebelt.Extensions.Carter/Response/ConfigurableResponseNegotiator.cs`
around lines 42 - 53, The CanHandle method mutates ContentType inside the LINQ
Any() predicate which creates side-effects and race conditions; change the logic
to first find a matching media type without mutation (e.g., use FirstOrDefault
or a simple loop over Options.SupportedMediaTypes and call
accept.MatchesMediaType(mediaType.MediaType)), then — outside the predicate —
set ContentType to the matched mediaType.MediaType if non-null and return
true/false accordingly; ensure you reference the CanHandle method,
Options.SupportedMediaTypes, ContentType, and MediaTypeHeaderValue accept when
making the change.
src/Codebelt.Extensions.Carter/Response/ConfigurableResponseNegotiator.cs
Outdated
Show resolved
Hide resolved
Welcome to Codecov 🎉Once you merge this PR into your default branch, you're all set! Codecov will compare coverage reports and display results in all future pull requests. Thanks for integrating Codecov - We've got you covered ☂️ |
|
This pull request sets up GitHub code scanning for this repository. Once the scans have completed and the checks have passed, the analysis results for this pull request branch will appear on this overview. Once you merge this pull request, the 'Security' tab will show more code scanning analysis results (for example, for the default branch). Depending on your configuration and choice of analysis tool, future pull requests will be annotated with code scanning analysis results. For more information about GitHub code scanning, check out the documentation. |
|
@gimlichael I've opened a new pull request, #2, to work on those changes. Once the pull request is ready, I'll request review from you. |
|
@gimlichael I've opened a new pull request, #3, to work on those changes. Once the pull request is ready, I'll request review from you. |
|
@gimlichael I've opened a new pull request, #4, to work on those changes. Once the pull request is ready, I'll request review from you. |
* Initial plan * fix: update LICENSE link in README.md to use correct filename Co-authored-by: gimlichael <8550919+gimlichael@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: gimlichael <8550919+gimlichael@users.noreply.github.com>
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In @.github/workflows/ci-pipeline.yml:
- Line 1: The file uses CRLF line endings causing YAML lint errors; convert the
workflow file so all lines use LF (\n). Update the top-level workflow text (the
line starting with "name: Carter CI Pipeline") to use LF endings, commit the
change, and optionally add or update a .gitattributes entry (e.g., "*.yml text
eol=lf") to enforce LF for YAML files so future commits remain LF-normalized.
- Line 26: Replace mutable workflow refs that use tag suffixes (e.g., the uses
entries referencing
codebeltnet/jobs-dotnet-build/.github/workflows/default.yml@v3) with immutable
full 40-character git commit SHAs; locate each "uses:" line that ends with "@v*"
(lines showing codebeltnet/jobs-dotnet-build/.github/workflows/default.yml@v3
and the similar entries at the other occurrences) and update the tag to the
repository's corresponding commit SHA (format @<40-char-sha>) so the workflow is
pinned to an immutable revision.
ℹ️ Review info
Configuration used: defaults
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
.docfx/images/128x128.pngis excluded by!**/*.png
📒 Files selected for processing (1)
.github/workflows/ci-pipeline.yml
| @@ -0,0 +1,117 @@ | |||
| name: Carter CI Pipeline | |||
There was a problem hiding this comment.
Use LF line endings to satisfy YAML lint.
Line 1 indicates CRLF usage; YAMLlint expects LF (\n). Please normalize this file’s line endings to LF to avoid CI lint failures.
🧰 Tools
🪛 YAMLlint (1.38.0)
[error] 1-1: wrong new line character: expected \n
(new-lines)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In @.github/workflows/ci-pipeline.yml at line 1, The file uses CRLF line endings
causing YAML lint errors; convert the workflow file so all lines use LF (\n).
Update the top-level workflow text (the line starting with "name: Carter CI
Pipeline") to use LF endings, commit the change, and optionally add or update a
.gitattributes entry (e.g., "*.yml text eol=lf") to enforce LF for YAML files so
future commits remain LF-normalized.
| matrix: | ||
| arch: [X64, ARM64] | ||
| configuration: [Debug, Release] | ||
| uses: codebeltnet/jobs-dotnet-build/.github/workflows/default.yml@v3 |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
cat -n .github/workflows/ci-pipeline.yml | head -120Repository: codebeltnet/carter
Length of output: 4679
🏁 Script executed:
#!/bin/bash
set -euo pipefail
rg -nP '^\s*uses:\s*[^@\s]+@(?!(?:[0-9a-fA-F]{40})\s*$)' .github/workflowsRepository: codebeltnet/carter
Length of output: 1576
Pin reusable workflow refs to immutable commit SHAs.
Lines 26, 40, 54, 71, 83, 93, 101, and 109 use mutable tags (@v*), which weakens workflow supply-chain integrity because tags can move. Pin each to a full 40-character commit SHA instead:
Required changes
- uses: codebeltnet/jobs-dotnet-build/.github/workflows/default.yml@v3
+ uses: codebeltnet/jobs-dotnet-build/.github/workflows/default.yml@<40-char-commit-sha>
- uses: codebeltnet/jobs-dotnet-pack/.github/workflows/default.yml@v3
+ uses: codebeltnet/jobs-dotnet-pack/.github/workflows/default.yml@<40-char-commit-sha>
- uses: codebeltnet/jobs-dotnet-test/.github/workflows/default.yml@v3
+ uses: codebeltnet/jobs-dotnet-test/.github/workflows/default.yml@<40-char-commit-sha>
- uses: codebeltnet/jobs-sonarcloud/.github/workflows/default.yml@v3
+ uses: codebeltnet/jobs-sonarcloud/.github/workflows/default.yml@<40-char-commit-sha>
- uses: codebeltnet/jobs-codecov/.github/workflows/default.yml@v1
+ uses: codebeltnet/jobs-codecov/.github/workflows/default.yml@<40-char-commit-sha>
- uses: codebeltnet/jobs-codeql/.github/workflows/default.yml@v3
+ uses: codebeltnet/jobs-codeql/.github/workflows/default.yml@<40-char-commit-sha>
- uses: codebeltnet/jobs-nuget-push/.github/workflows/default.yml@v2
+ uses: codebeltnet/jobs-nuget-push/.github/workflows/default.yml@<40-char-commit-sha>🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In @.github/workflows/ci-pipeline.yml at line 26, Replace mutable workflow refs
that use tag suffixes (e.g., the uses entries referencing
codebeltnet/jobs-dotnet-build/.github/workflows/default.yml@v3) with immutable
full 40-character git commit SHAs; locate each "uses:" line that ends with "@v*"
(lines showing codebeltnet/jobs-dotnet-build/.github/workflows/default.yml@v3
and the similar entries at the other occurrences) and update the tag to the
repository's corresponding commit SHA (format @<40-char-sha>) so the workflow is
pinned to an immutable revision.
…ept-Charset header is absent (#3) * Initial plan * fix: add null-conditional operator to prevent NullReferenceException on AcceptCharset.Count Co-authored-by: gimlichael <8550919+gimlichael@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: gimlichael <8550919+gimlichael@users.noreply.github.com>
…rableResponseNegotiator (#4) * Initial plan * fix: use leaveOpen:true in StreamWriter to avoid disposing HttpResponse.Body Co-authored-by: gimlichael <8550919+gimlichael@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: gimlichael <8550919+gimlichael@users.noreply.github.com>
|



This pull request sets up documentation generation, publishing, and project metadata for the "Extensions for Carter by Codebelt" project. It introduces DocFX configuration, Docker-based build and publish scripts, API documentation for namespaces, and project-wide code style rules. The changes are organized into three main themes: documentation infrastructure, API documentation, and project standards.
Documentation infrastructure:
docfx.json) to generate documentation for all relevant Carter extension projects, including metadata sources, build settings, templates, and global metadata.BuildDocfxImage.ps1,PublishDocfxImage.ps1,Dockerfile.docfx) to automate documentation generation and deployment for multiple platforms. [1] [2] [3]toc.yml) and frontpage (index.md) for the documentation site. [1] [2]API documentation:
System.Objectfrom API docs. [1] [2]Project standards and policies:
.editorconfigto enforce code style, formatting, and analyzer rules across C#, VB, and XML files.Summary by CodeRabbit
New Features
Documentation
Tests
Chores