feat: generate README plugin docs with an MSBuild C# task - #38
Merged
Merged
Conversation
Add Update-ReadmeDocs.ps1, a VS Code task and an update-readme-docs skill to generate plugin docs locally. Remove the robot-docs CI caller.
Replace the Python metadata.py + PowerShell pipeline with build/ReadmeDocs.cs, compiled by RoslynCodeTaskFactory and run by the UpdateReadmeDocs target (dotnet msbuild -t:UpdateReadmeDocs). Only the .NET SDK is required and it runs offline. CI builds (CI=true) regenerate the sections in memory and fail with PDREADME005 when README.md is stale. The port matches metadata.py output except that it is deterministic, lists each Minimum Essentials Framework Version once, finds factories and join maps by content rather than file name (recovering join maps metadata.py skipped), classifies IpTableObjectBase-style names correctly, and lists Base Classes before Interfaces as plain items. Badges now read MinimumEssentialsFrameworkVersion from any project C# file, so factories can be renamed freely. Remove Update-ReadmeDocs.ps1 and update the README, VS Code task and the update-readme-docs skill. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Copyright: README heading 2026, LICENSE "2020-2026" (placeholder brackets removed); the csproj no longer overrides the props copyright - csproj keeps only plugin-specific values; shared Version, Company, Authors and Copyright come from Directory.Build.props. PackageId uses "PepperDash" casing, PackageProjectUrl drops ".git", PackageTags are set once, and the duplicate hard-coded .cplz None Remove lines are removed - Remove the uncompiled Properties/AssemblyInfo.cs and empty ControlSystem.cfg and .gitmodules - Factory and class doc comments: rename examples use the current class names, valid MinimumEssentialsFrameworkVersion examples, per-category TypeNames examples, and correct BuildDevice summaries; fix ASCII, delimiter and TODO typos - Docs: README, skill, generator header and commit-msg hook comment describe the generator's actual differences from metadata.py and CI behavior Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…axis Placeholders: - Replace the remaining EssentialsPluginTemplate names: the join map class is MakeModelBridgeJoinMap, Product/Description say "Make Model", and the repository URLs use the epi-make-model placeholder - Namespace and RootNamespace are PepperDash.Essentials.Plugins.MakeModel; AssemblyTitle and PackageId are PepperDash.Essentials.Plugins.Make.Model - Rename MakeModelConfigObject.cs to MakeModelPropertiesConfig.cs, with the classes MakeModelPropertiesConfig and MakeModelPropertiesConfigDictionary - Drop "template" from PackageTags README: - Organize the hand-written sections as Tutorial, How-to guides, Reference and Explanation; the tutorial was verified end to end on a scratch clone - Add reference tables for the repository layout, placeholder names, build outputs, targets, properties, PDREADME error codes, badges and generated sections - Update the update-readme-docs skill for the renamed config class Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
The generator mishandles skipped sections, multiple minimum versions per file, and writable join capabilities.
Review effort: Balanced
Findings: 3
Open (3)
What changed in this PR
Moves README plugin-documentation generation into MSBuild while modernizing template naming and documentation.
Changes:
- Adds the C# README generator and MSBuild update/check targets.
- Reorganizes README guidance and removes the legacy workflow.
- Normalizes namespaces, class names, and package metadata.
| File | Description |
|---|---|
build/ReadmeDocs.cs |
Implements documentation generation. |
src/Directory.Build.targets |
Adds README generation and validation targets. |
src/Directory.Build.props |
Updates shared package metadata. |
README.md |
Adds comprehensive template and generated documentation. |
.github/skills/update-readme-docs/SKILL.md |
Adds README maintenance guidance. |
.github/workflows/essentialsplugins-updatereadme-caller.yml |
Removes the legacy generation workflow. |
.vscode/tasks.json |
Adds the README update task. |
.husky/commit-msg |
Clarifies hook documentation. |
src/epi-make-model.4Series.csproj |
Updates namespace and package metadata. |
src/MakeModelPropertiesConfig.cs |
Renames and namespaces configuration types. |
src/MakeModelBridgeJoinMap.cs |
Renames and namespaces the join map. |
src/MakeModelDevice.cs |
Uses renamed configuration and join-map types. |
src/MakeModelDeviceFactory.cs |
Uses the renamed configuration type. |
src/MakeModelLogicDevice.cs |
Uses renamed template types. |
src/MakeModelLogicDeviceFactory.cs |
Uses the renamed configuration type. |
src/MakeModelCrestronDevice.cs |
Uses renamed template types. |
src/MakeModelCrestronDeviceFactory.cs |
Uses the renamed configuration type. |
src/Properties/AssemblyInfo.cs |
Removes legacy manual assembly attributes. |
LICENSE.md |
Updates the copyright range. |
src/Properties/ControlSystem.cfg |
No substantive textual change shown. |
.gitmodules |
No substantive textual change shown. |
💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
- Collect every MinimumEssentialsFrameworkVersion in a file (Matches), not just the first - Render join access as R, W or R/W from JoinCapabilities instead of always R - Document that SKIP still lets the Config Example's type and uid be updated Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Fill each property from the first <example><code> block containing its JSON name - Default pollTimeMs, warningTimeoutMs and errorTimeoutMs to 30000, 180000 and 300000 - Use realistic key, name and group values - Ignore <!-- SKIP --> in the Config Example so it always follows the code - Fix the template config examples (pollTimeMs, control, DeviceDictionary) - Document setting Config Example values in README and the update-readme-docs skill Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Summary
Moves README plugin-documentation generation (config example, supported types, join maps, base classes, interfaces, public methods, feedbacks) into the build. Previously it ran Python
metadata.pyplus a PowerShell script; now it is a C# MSBuild task, so it works on Windows and macOS with only the .NET SDK. It builds on the MSBuild badge generation already ingit-config-updates.What changed
build/ReadmeDocs.cs: C# port ofmetadata.py(workflow-templates681f68e) plus the template's post-processing.RoslynCodeTaskFactorycompiles it at build time; it sits outsidesrc/, so it is never part of the plugin.src/Directory.Build.targets:UpdateReadmeDocsregenerates the docs. Rundotnet msbuild -t:UpdateReadmeDocsor the VS Code task "Update README docs", then review and commit.CheckReadmeDocs: CI builds (CI=true) regenerate in memory and fail withPDREADME005whenREADME.mdis stale.feature/local-readme-docs, copied rather than rebased, so that branch's history is untouched. That commit reorganizes the README, adds theupdate-readme-docsskill, and removes the robot-docs workflow caller.Update-ReadmeDocs.ps1, so Python and pwsh are no longer required anywhere.MakeModelDevice.cs.Why
metadata.pyused file-system order and an unordered set, so Supported Types could reorder between runs.SonyBraviaDeviceFactory, or a join map whose file doesn't match its class name, is still found.Differences from metadata.py output
The output matches
metadata.pybyte for byte, except for these intentional changes:<!-- SKIP -->workaround that had frozen this section at 2.12.1 is removed.<ClassName>.cs.metadata.pysilently left the section empty in these cases.IpTableObjectBaseas an interface.Testing
metadata.pywith sorted directory traversal, plus the old post-processing) were run on 31 local plugin repos, including Essentials, epi-crestron-nvx and epi-qsc-qsysdsp.dotnet build -p:CI=truefail withPDREADME005; afterUpdateReadmeDocs, it passes.MakeModelDeviceFactorybecameSonyBraviaDeviceFactory.Factories.cs.JoinMap.cs.-p:CI=true, it passed.Notes for reviewers
typeis the firstTypeNamesentry in the first file, sorted by name, that setsTypeNames. For a different type, edit the section and mark it<!-- SKIP -->.metadata.pyin workflow-templates is still used by the legacyupdate-readme.ymlfor other plugins. From now on, a fix in one won't reach the other automatically.getVersionreports a new version. Ordinary pushes aren't checked.🤖 Generated with Claude Code