Skip to content

feat(docs): add api-docs template for dotnet-sdk (xmldocmd)#15

Merged
WomB0ComB0 merged 5 commits intomainfrom
feat/api-docs-dotnet-template
May 9, 2026
Merged

feat(docs): add api-docs template for dotnet-sdk (xmldocmd)#15
WomB0ComB0 merged 5 commits intomainfrom
feat/api-docs-dotnet-template

Conversation

@WomB0ComB0
Copy link
Copy Markdown
Member

@WomB0ComB0 WomB0ComB0 commented May 9, 2026

Summary

Adds the second per-language workflow template, mirroring the TypeScript pipeline for .NET.

  • New file: automation/source-repo-templates/api-docs.dotnet.yml
  • README table: dotnet-sdk row updated from DocFX / _TODO_ placeholder to xmldocmd / api-docs.dotnet.yml

Pipeline

  1. actions/setup-dotnet honoring global.json (.NET 9 today).
  2. dotnet build -c Release -p:GenerateDocumentationFile=true to emit the per-project XML doc files alongside DLLs.
  3. dotnet tool install -g xmldocmd then iterate over six packable projects (ResQ.Clients, ResQ.Core, ResQ.Protocols, ResQ.Blockchain, ResQ.Storage, ResQ.Simulation), invoking xmldocmd <dll> <out>/<proj> --visibility public --clean.
  4. Same Mintlify-safety post-processing as the TypeScript template:
    • ./ prefix on bare-filename .md links
    • MDX curly-brace escape outside code regions (awk tracks both fences and inline backtick spans)
  5. peter-evans/create-pull-request opens a PR back to resq-software/docs against main, branch auto/dotnet-api-<ref>, authored as resq-sw.

Why xmldocmd over DocFX

xmldocmd is a purpose-built CLI tool that takes a DLL + XML pair and produces Markdown. DocFX is more powerful but its Markdown output requires a custom template (its native output is HTML). For the simpler shape we want, xmldocmd is one-step.

Test plan

  • Merge.
  • Open a follow-up PR in resq-software/dotnet-sdk copying this file to .github/workflows/api-docs.yml.
  • Trigger via workflow_dispatch and inspect the resulting docs PR for unexpected post-processing failures.
  • If new generator-specific quirks appear (breadcrumb noise, anchor format, etc.), iterate the template here first then sync to dotnet-sdk.

Out of scope

  • Wiring nav for sdks/dotnet/api/ in docs.json (deferred along with the TypeScript nav).
  • Templates for Python (mkdocstrings), Rust (rustdoc), C++ (Doxygen), and viz.

Summary by CodeRabbit

  • Documentation

    • Updated API documentation tooling configuration for the C# SDK.
  • Automation

    • Added automated workflow to generate .NET API documentation, post-process content, and sync updates to the documentation repository via automated pull requests.

Mirrors the TypeScript pipeline for .NET. Iterates over every
IsPackable project in the solution, builds Release with
GenerateDocumentationFile=true, then runs xmldocmd against each
DLL/XML pair to produce a per-package Markdown tree. Reuses the
same Mintlify-safety post-processing as the TypeScript template
(./ prefix on bare-filename links, MDX curly-brace escape outside
code regions) and opens a PR via peter-evans/create-pull-request
authored as resq-sw.

Picked xmldocmd over DocFX because DocFX's Markdown story
requires a custom template; xmldocmd is purpose-built for the
DLL+XML -> Markdown conversion with a single shell invocation.
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 9, 2026

Review Change Stack

Warning

Rate limit exceeded

@WomB0ComB0 has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 30 minutes and 37 seconds before requesting another review.

You’ve run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

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.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 208145a8-f38a-424c-969c-9e7c01f6d422

📥 Commits

Reviewing files that changed from the base of the PR and between 7f7875c and 65a4f1c.

📒 Files selected for processing (2)
  • automation/source-repo-templates/README.md
  • automation/source-repo-templates/api-docs.dotnet.yml
📝 Walkthrough

Walkthrough

This pull request introduces a GitHub Actions workflow that automates .NET API documentation generation. The workflow checks out source, builds projects to generate XML docs, converts them to Markdown via xmldocmd, post-processes the Markdown for link safety and MDX compatibility, syncs to a docs repository, and creates a PR. The README is updated to reference the new workflow template.

Changes

.NET API Documentation Automation

Layer / File(s) Summary
Workflow Declaration & Triggers
automation/source-repo-templates/api-docs.dotnet.yml
Workflow api-docs triggers on v* tags and manual dispatch with optional ref input; permissions and concurrency configured to force-cancel in-flight runs.
Job Setup & Environment
automation/source-repo-templates/api-docs.dotnet.yml
Job defines runner settings, timeout, and environment variables for solution path, output directories, target docs path, and list of public projects to document.
Source Checkout & Build
automation/source-repo-templates/api-docs.dotnet.yml
Checks out source at requested ref, installs .NET via global.json, restores solution, and builds Release configuration to generate XML documentation.
API Documentation Generation
automation/source-repo-templates/api-docs.dotnet.yml
Installs xmldocmd tool and generates per-project Markdown trees from built DLLs under bin/Release/net9.0/.
Markdown Post-Processing
automation/source-repo-templates/api-docs.dotnet.yml
Writes top-level README.md, prefixes bare .md intra-page links with ./ via find + sed, and escapes { } to HTML entities outside code blocks via awk for MDX safety.
Index Creation & Repository Sync
automation/source-repo-templates/api-docs.dotnet.yml
Creates _pages.json index, checks out resq-software/docs repo, deletes old content, and syncs generated Markdown to sdks/dotnet/api.
Pull Request Creation
automation/source-repo-templates/api-docs.dotnet.yml
Opens or updates PR in docs repo with scoped paths, deterministic auto-generated branch name, and configured cleanup.
Template Registry Update
automation/source-repo-templates/README.md
Updates tooling table to reference xmldocmd with template api-docs.dotnet.yml for .NET SDK documentation.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 A rabbit hops through workflows new,
xmldocmd turns DLLs true to view,
Markdown grows with each tag's release,
Links are fixed, the {} find peace,
To the docs repo, a PR takes flight!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically describes the main change: adding a new API documentation template for .NET SDK using xmldocmd, which aligns with the primary objective of the PR.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/api-docs-dotnet-template

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@automation/source-repo-templates/api-docs.dotnet.yml`:
- Around line 103-113: The current loop over PUBLIC_PROJECTS skips missing
assembly files with a warning which can lead to a destructive sync publishing
incomplete docs; modify the check around
dll="${proj}/bin/Release/net9.0/${proj}.dll" so that if [ ! -f "$dll" ] then
emit an error and exit with a non-zero status (fail the job) instead of
continuing, ensuring the workflow halts before the later destructive sync (see
the loop and the xmldocmd invocation that writes to OUTPUT_DIR/$proj); apply the
same failing behavior to the other similar check at lines 206-212.
- Around line 42-43: The workflow mixes github.ref/github.ref_name and
inputs.ref causing inconsistent branch names and PR collisions; resolve the
requested ref once (e.g., compute a single resolved_ref from inputs.ref ||
github.ref_name in a step or job-level env) and use that resolved_ref
everywhere—replace group: api-docs-${{ github.ref }}, the checkout step(s) that
currently use inputs.ref, and the PR/branch name construction (the logic around
creating the docs PR branch) to reference the single resolved_ref variable
(e.g., env.RESOLVED_REF or a step output like steps.resolve_ref.outputs.ref) so
all metadata and branch names are consistent for workflow_dispatch and other
triggers.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 9afb5d79-b666-4e38-a5b7-094962818146

📥 Commits

Reviewing files that changed from the base of the PR and between 0c8af02 and 7f7875c.

📒 Files selected for processing (2)
  • automation/source-repo-templates/README.md
  • automation/source-repo-templates/api-docs.dotnet.yml

Comment thread automation/source-repo-templates/api-docs.dotnet.yml Outdated
Comment thread automation/source-repo-templates/api-docs.dotnet.yml
…semblies

Resolves CodeRabbit review threads on PR #15:

- Compute DOCS_REF_NAME / DOCS_REF_SLUG once from inputs.ref ||
  github.ref_name and use them for the docs PR commit message,
  title, body, and branch name. Also key the concurrency group
  off inputs.ref || github.ref so workflow_dispatch runs against
  alternate refs no longer collide with the default branch.
- Track missing assemblies as errors and exit non-zero when any
  expected project DLL is absent or none were generated, so the
  later destructive sync into sdks/dotnet/api/ never publishes a
  partial API surface.
Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a new GitHub Actions workflow template, api-docs.dotnet.yml, designed to automate the generation of .NET API documentation using xmldocmd. The workflow handles building the solution, generating Markdown documentation for public projects, and performing post-processing for MDX compatibility before opening a pull request in the central documentation repository. Feedback focuses on improving the template's maintainability and robustness by dynamically discovering packable projects and locating build artifacts instead of relying on hardcoded paths and project lists.

Comment thread automation/source-repo-templates/api-docs.dotnet.yml Outdated
Comment thread automation/source-repo-templates/api-docs.dotnet.yml
xmldocmd's first run on dotnet-sdk failed with
FileNotFoundException for System.Runtime 9.0.0.0. Root cause:
xmldocmd uses MetadataLoadContext to read assembly metadata, and
its resolver scans only the directory of the target DLL for
referenced assemblies. `dotnet build` for class libraries does
not copy transitive package/contract assemblies into bin; only
`dotnet publish` does.

Add an explicit publish pass per project after build. xmldocmd
then reads from bin/Release/net9.0/publish/<Project>.dll where
the full dependency closure is sitting next to the target.
WomB0ComB0 added a commit to resq-software/dotnet-sdk that referenced this pull request May 9, 2026
Sync source-of-truth template (resq-software/docs#15) updates:

* Add a publish step after build. xmldocmd uses MetadataLoadContext
  which scans only the directory of the target DLL for referenced
  assemblies. `dotnet build` for class libraries does not copy
  transitive contract assemblies (e.g. System.Runtime); `dotnet
  publish` does. Point xmldocmd at bin/Release/net9.0/publish/.
* Resolve the source ref once into DOCS_REF_NAME / DOCS_REF_SLUG so
  workflow_dispatch with an alternate ref consistently flows through
  PR/branch names without /-vs-tag inconsistencies.
* Use `set -euo pipefail` and fail the run if any project's
  assembly is missing or zero packages produced output. Avoids
  syncing partial/empty docs output to the docs repo.

First run (https://github.com/resq-software/dotnet-sdk/actions/runs/25590261716)
failed at xmldocmd with FileNotFoundException for System.Runtime
9.0.0.0; this addresses the root cause.
WomB0ComB0 added a commit to resq-software/dotnet-sdk that referenced this pull request May 9, 2026
)

Sync source-of-truth template (resq-software/docs#15) updates:

* Add a publish step after build. xmldocmd uses MetadataLoadContext
  which scans only the directory of the target DLL for referenced
  assemblies. `dotnet build` for class libraries does not copy
  transitive contract assemblies (e.g. System.Runtime); `dotnet
  publish` does. Point xmldocmd at bin/Release/net9.0/publish/.
* Resolve the source ref once into DOCS_REF_NAME / DOCS_REF_SLUG so
  workflow_dispatch with an alternate ref consistently flows through
  PR/branch names without /-vs-tag inconsistencies.
* Use `set -euo pipefail` and fail the run if any project's
  assembly is missing or zero packages produced output. Avoids
  syncing partial/empty docs output to the docs repo.

First run (https://github.com/resq-software/dotnet-sdk/actions/runs/25590261716)
failed at xmldocmd with FileNotFoundException for System.Runtime
9.0.0.0; this addresses the root cause.
WomB0ComB0 added 2 commits May 8, 2026 23:37
xmldocmd uses MetadataLoadContext to read assembly metadata, and
its PathAssemblyResolver scans only the directory of the target
DLL for transitive dependencies. .NET 9 class library output does
not include System.Runtime contract DLLs even after dotnet
publish, so xmldocmd hits FileNotFoundException for every loaded
assembly:

  System.IO.FileNotFoundException: Could not load file or assembly
  'System.Runtime, Version=9.0.0.0, ...'

DefaultDocumentation.Console reads with Mono.Cecil, which parses
the assembly bytes directly without resolving against a runtime,
so cross-version reads just work. Drop the now-unnecessary publish
step and update the per-language tooling table.
Addresses pr#15 review feedback. global.json pins the SDK feature
band but not the project TFM. Replacing
  bin/Release/net9.0/<Project>.dll
with a `find` over `bin/Release/*/` lets a net10 upgrade roll
through without a workflow edit.
@WomB0ComB0 WomB0ComB0 merged commit 960ad0d into main May 9, 2026
13 checks passed
@WomB0ComB0 WomB0ComB0 deleted the feat/api-docs-dotnet-template branch May 9, 2026 03:45
WomB0ComB0 added a commit to resq-software/dotnet-sdk that referenced this pull request May 9, 2026
Mintlify's URL parser splits link targets at the first '#'.
DefaultDocumentation names constructor pages '<Type>.#ctor.md'
following the IL convention, so a link like
  Foo.#ctor.md#Foo.Foo(string)
parses as path='Foo.' (does not exist) and fragment='ctor.md#...'.

Rename '*.#ctor.md' -> '*.ctor.md' and rewrite the substring
'.#ctor.md' in all remaining content. Sync source-of-truth from
resq-software/docs#15.
resq-sw pushed a commit to resq-software/dotnet-sdk that referenced this pull request May 9, 2026
Mintlify's URL parser splits link targets at the first '#'.
DefaultDocumentation names constructor pages '<Type>.#ctor.md'
following the IL convention, so a link like
  Foo.#ctor.md#Foo.Foo(string)
parses as path='Foo.' (does not exist) and fragment='ctor.md#...'.

Rename '*.#ctor.md' -> '*.ctor.md' and rewrite the substring
'.#ctor.md' in all remaining content. Sync source-of-truth from
resq-software/docs#15.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:content MDX/MD documentation content

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant