Replace docs JSON-RPC methods with bicep/renderDocs and bicep/getDocsModel - #20209
Closed
Jared Holgate (jaredfholgate) wants to merge 2 commits into
Closed
Jared Holgate (jaredfholgate) wants to merge 2 commits into
Jared Holgate (jaredfholgate) wants to merge 2 commits into
Conversation
Replaces bicep/generateDocs and bicep/outputDocs with bicep/renderDocs and bicep/getDocsModel, and marks both as experimental. generateDocs was the only RPC method that wrote to disk. bicep/compile is the RPC counterpart of bicep build and returns Contents rather than writing main.json; renderDocs now follows that convention. The CLI merged docs output into docs generate --stdout, so splitting two methods by output destination no longer matched any command. getDocsModel returns the typed documentation model, which previously required rendering Markdown and parsing it back. getDocsModel resolves options from bicepconfig.json so usage-example discovery and configured custom values match what renderDocs and the CLI produce. Also corrects the client version gate from 0.46.0 to 0.47.0. Both 0.46.0 and 0.46.1 shipped before the docs feature merged, so the old gate let clients pass the check and then fail with method not found. Fixes BaselineHelper.GetRepoRoot to accept a .git file as a repo-root marker so baseline tests run from a git worktree, where .git is a file rather than a directory. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Contributor
|
Test this change out locally with the following install scripts (Action run 32820517719) VSCode
Azure CLI
|
Jared Holgate (jaredfholgate)
marked this pull request as ready for review
August 20, 2026 16:29
Jared Holgate (jaredfholgate)
requested a review
from Anthony Martin (anthony-c-martin)
August 20, 2026 16:29
Member
Author
|
Copilot resolve the merge conflicts on this branch. |
Co-authored-by: jaredfholgate <1612200+jaredfholgate@users.noreply.github.com>
Contributor
Resolved. I merged |
Member
Author
|
Replaced with #20215 |
Jared Holgate (jaredfholgate)
deleted the
jaredfholgate-docs-rpc-surface-rework
branch
September 3, 2026 09:17
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.
Description
Replaces the two experimental docs JSON-RPC methods with better-shaped ones, and marks them experimental.
bicep/generateDocs(writes files, takesPaths[])bicep/renderDocs— returns rendered content, never writesbicep/outputDocs(returns content, takes singlePath)bicep/getDocsModel— returns the typed documentation model as JSONFollow-up to #20183, which introduced these methods. The RPC surface was questioned during review.
Why
No other RPC method writes to disk. The only file-write call in
CliJsonRpcServer.cswas insideGenerateDocs.bicep/compileis the RPC counterpart ofbicep build, and it deliberately returnsContentsvia aStringWriterrather than writingmain.json. The established convention is that RPC returns content and the client owns the filesystem —generateDocsbroke it.The CLI merged
docs outputintodocs generate --stdout, so two RPC methods split by output destination had become a stale echo of a command that no longer exists. Splitting by what is returned (rendered text vs typed model) is meaningful; splitting by where it goes is not.outputDocswas misnamed. "Output" describes a destination, not an operation, and appeared nowhere else in the protocol.rendermatchescompile/formatas a transformation verb and is already the codebase's own term (IBicepDocumentationGenerator.Render).getDocsModelfills a real gap and follows theget*family (getMetadata,getSnapshot,getDeploymentGraph,getFileReferences).GetMetadataResponseis the precedent for returning a structured model, but it is much shallower — name, type name, description, range. The docs model adds allowed values, numeric and length bounds, patterns, nested properties, discriminator cases, exported types/variables/functions, cross-referenced modules and usage examples. Previously a tool wanting that data had to render Markdown and parse it back.Breaking change to
ICliJsonRpcProtocolICliJsonRpcProtocolcarries a stability guarantee as of Bicep 0.29, so this is called out deliberately. It is justified because thebicep docsfeature is experimental and has no known RPC consumers:bicep/generateDocs/bicep/outputDocsreturns 5 results. Four are in this repo; the fifth isAzure/bicep-repsactive/0025-module-documentation-generation.md, the design proposal — not a consumer.The conflicting stability promises are now resolved explicitly: both methods and all docs-specific records carry
<remarks>stating they may change while thebicep docsfeature remains experimental, notwithstanding the guarantee for the rest of the interface.Pathsarray is a deliberate deviationEvery other RPC method takes a single
Path. These two takePaths[], for these reasons:ActiveSourceFileSetoptimisation depends on batching, so a batch reuses parsed source files across modules.generateDocsalready established the precedent.Both return one result per requested path in request order, and a failure for one path does not prevent the others from being processed.
getDocsModeland configurationgetDocsModeltakes no template options — the model is built before rendering, sotemplateFile/templateRoot/custom values are meaningless there. It does still resolve options frombicepconfig.json, because configuration shapes the model itself:BuildModel(compilation, customValues, ct)passes defaultDocumentationExamples, whereasbicep docs generateresolves them from config. Without this, a repo setting"examples": { "sources": [] }would get different usage examples fromgetDocsModelthan fromrenderDocs.documentation.template.valuespopulates the model'scustomfield.So the returned model matches what
renderDocsand the CLI render from. Configuration continues to be resolved independently for each requested file, so one batch may mix modules with different templates, custom values and example settings.Included fixes
Version gate corrected from
0.46.0to0.47.0. v0.46.0 and v0.46.1 both released on 2026-07-30, and the docs commit (0761a86b11a0) is 38 commits ahead ofv0.46.1— the docs methods shipped in neither. A client on v0.46.1 passedEnsureMinimumVersionand then failed with "method not found".BaselineHelper.GetRepoRoot()now accepts a.gitfile. It searched for a.gitdirectory, but in a linked git worktree.gitis a file containing agitdir:pointer. The static initialiser threw, so every baseline test failed withTypeInitializationException— includingPublicApiTests, which made it impossible to regenerateAzure.Bicep.RpcClient.txtviaSetBaseLine=true. One line, and it unblocks ~132 baseline tests for anyone working in a worktree.Dead code removed.
OutputWriterexisted onCliJsonRpcServerandJsonRpcCommandsolely for the docs write path, along withDocsTargetandValidateDocsOutputFileName.Known gap
Neither method exposes the configured
documentation.output.file, so a client wanting to reproducebicep docs generatefile naming chooses its own filename. This is intentional — it keepsDocsResultaligned withCompileResponse— and is documented.Example Usage
bicep/renderDocs:{ "jsonrpc": "2.0", "id": 1, "method": "bicep/renderDocs", "params": { "paths": ["/repo/modules/storage/main.bicep"], "templateFile": null, "templateRoot": null, "customTemplateValues": { "owner": "Platform Team" }, "noRestore": false } }{ "jsonrpc": "2.0", "id": 1, "result": { "results": [ { "path": "/repo/modules/storage/main.bicep", "success": true, "diagnostics": [], "contents": "# Storage Account\n\nDeploys a storage account.\n" } ] } }bicep/getDocsModelreturns the same data pre-render, using the protocol's own field names (typeName,isRequired,isSecure,isExisting,isTruncated,nestedProperties). The template-only helpersdefaultValueFenceandfenceare excluded, being Markdown rendering aids rather than model data.From C#:
Full request/response payloads for both methods are in
docs/experimental/docs-commands.md.Documentation
docs/bicep-rpc-client.mdgains Render docs and Get docs model sections. This file documented 8 operations and omitted both docs methods entirely — they were the only ones missing.docs/experimental/docs-commands.mdhas a rewritten## JSON-RPCsection with per-method parameter tables, complete JSON-RPC request and response examples, and a C# example.Both state the experimental caveat and that neither method writes files.
Validation
Build is clean at 0 warnings (
TreatWarningsAsErrors). ~11,900 tests pass, 0 failures:Bicep.Core.UnitTestsBicep.Core.IntegrationTestsBicep.Cli.IntegrationTestsBicep.Decompiler.IntegrationTestsBicep.RpcClient.TestsBicep.Cli.UnitTestsThe public API baseline was regenerated with
--filter TestCategory=Baseline --test-parameter SetBaseLine=true, not hand-edited.New JSON-RPC integration tests cover multiple paths in one request, a compilation failure among successes with request order preserved, a custom template via
TemplateFilewith includes and custom values, template settings coming frombicepconfig.jsonrather than the request, per-module configuration resolution in a single batch, cancellation threading intoBuildModel/Render, structured failures, a fully populated model, and assertions that no files are written. A System.Text.Json round-trip test covers the model'sImmutableSortedDictionaryand nestedImmutableArraymembers on netstandard2.0.Checklist
Microsoft Reviewers: Open in CodeFlow