Skip to content

docs: Document the docs/ schema conversion for consumers - #180

Merged
tablackburn merged 1 commit into
mainfrom
docs/154-consumer-docs-schema-conversion
Aug 26, 2026
Merged

tablackburn merged 1 commit into
mainfrom
docs/154-consumer-docs-schema-conversion

Conversation

@tablackburn

Copy link
Copy Markdown
Contributor

Summary

  • Adds a migration entry, "A committed docs/ tree converts itself on the first build",
    telling consumers how to move a committed docs/ tree from the platyPS 0.14.x schema to the
    Microsoft.PowerShell.PlatyPS 1.x schema, plus a Quick Start bullet linking to it.
  • Replaces the #154 placeholder in the "Generated markdown uses the PlatyPS 1.x schema"
    entry with a link to the new entry.
  • Every claim in the entry was run, not transcribed. See the verification log below.

Closes #154

The headline finding

The issue framed this as "document the one-shot." Running it showed the one-shot is usually
unnecessary. Build-PSBuildMarkdown already calls Update-MarkdownCommandHelp over every
existing command document on every build, and that cmdlet rewrites a 0.14.x document into the
1.x schema in place. A committed 0.14.x tree converts itself on the first 1.0.0 build,
landing page included:

=== docs tree BEFORE the build (genuine 0.14.x) ===
  Get-ScratchWidget.md         CommandHelp, V1Schema
  New-ScratchWidget.md         CommandHelp, V1Schema
  Remove-ScratchWidget.md      CommandHelp, V1Schema
  ScratchModule.md             ModuleFile, V1Schema

=== docs tree AFTER the build ===
  Get-ScratchWidget.md         CommandHelp, V2Schema
  New-ScratchWidget.md         CommandHelp, V2Schema
  Remove-ScratchWidget.md      CommandHelp, V2Schema
  ScratchModule.md             ModuleFile, V2Schema

So the entry reframes the work as reading the diff the build produces rather than running a
conversion, and keeps a manual path for the case where you want the conversion as its own
reviewable commit.

Where the snippet in the issue is wrong

The issue's proposed one-shot ends with
Export-MarkdownCommandHelp -OutputFolder .\docs\en-US -Force. Run verbatim against a real
0.14.x tree, it does not convert anything in docs/en-US. Export-MarkdownCommandHelp
always appends the module name to -OutputFolder:

--- files changed versus baseline ---
  Get-ScratchWidget.md         unchanged
  New-ScratchWidget.md         unchanged
  Remove-ScratchWidget.md      unchanged
  ScratchModule.md             unchanged
--- directory tree after the one-shot ---
  \docs\en-US\Get-ScratchWidget.md          <- still schema: 2.0.0
  \docs\en-US\New-ScratchWidget.md          <- still schema: 2.0.0
  \docs\en-US\Remove-ScratchWidget.md       <- still schema: 2.0.0
  \docs\en-US\ScratchModule.md
  \docs\en-US\ScratchModule\Get-ScratchWidget.md      <- the converted copies land here
  \docs\en-US\ScratchModule\New-ScratchWidget.md
  \docs\en-US\ScratchModule\Remove-ScratchWidget.md

It exits 0 and looks like it worked. This is the same nesting Build-PSBuildMarkdown already
works around with a staging directory. The entry documents Update-MarkdownCommandHelp as the
in-place one-shot instead, and calls out the export pipeline explicitly as a trap.

Verification method

A throwaway module (three functions, hand-written .EXAMPLE and .NOTES in comment-based
help) in $env:TEMP. Genuine 0.14.x markdown generated by platyPS 0.14.2; conversion run
under Microsoft.PowerShell.PlatyPS 1.0.3. Separate pwsh -NoProfile -File processes for
each half — the two modules ship conflicting YamlDotNet assemblies and cannot coexist in one
session. Before converting, the generated markdown was hand-edited with seven HANDWRITTEN-*
markers so content loss would be visible.

What was verified

Content survival

=== hand-written marker survival through a PowerShellBuild build ===
  HANDWRITTEN-DESCRIPTION      SURVIVED
  HANDWRITTEN-EXAMPLE          SURVIVED
  HANDWRITTEN-PARAMETER        SURVIVED
  HANDWRITTEN-INPUTS           SURVIVED
  HANDWRITTEN-OUTPUTS          SURVIVED
  HANDWRITTEN-NOTES            SURVIVED
  HANDWRITTEN-CUSTOM-SECTION   LOST

Hand-written examples and notes survive. A heading outside the PlatyPS schema (## CAVEATS)
is dropped with no warning and no error
— that is the real content-loss hazard, and it is the
same in both the update and the export paths.

A new hazard the issue did not anticipate

An edited parameter description is appended to, not replaced, and it compounds on every
build. After one build:

### -IncludeHidden

Include widgets that are marked as hidden. HANDWRITTEN-PARAMETER text.
Include widgets that are marked as hidden.

After two:

Include widgets that are marked as hidden. HANDWRITTEN-PARAMETER text.
Include widgets that are marked as hidden.
Include widgets that are marked as hidden.

Parameter descriptions that match comment-based help are unaffected. Documented with the fix
(make comment-based help the source of truth for parameter descriptions).

Front matter

# Before (0.14.x)                      # After (1.0.0)
external help file: …-help.xml         document type: cmdlet
Module Name: ScratchModule             external help file: …-help.xml
online version: https://…              HelpUri: https://…
schema: 2.0.0                          Module Name: ScratchModule
                                       ms.date: 08/26/2026
                                       PlatyPS schema version: 2024-05-01

external help file: is carried across byte for byte, so the 0.14.x lowercase
<Module>-help.xml spelling that PowerShellBuild pins survives and .ExternalHelp keeps
resolving on case-sensitive file systems. ms.date: is added by the update path only, not by
the export path.

The -NoBackup hazard (PowerShell/platyPS#863)

  run 1 (no -NoBackup) errors: 0; files:
    Get-ScratchWidget.md
    Get-ScratchWidget.md.bak
    …
  run 2 (no -NoBackup) errors: 3
    IOException: Cannot create a file when that file already exists.

Confirmed, and confirmed that -NoBackup makes it repeatable.

The landing-page hazard (PowerShell/platyPS#862)

Confirmed for MAML — an unfiltered batch writes nothing at all:

=== MAML export WITHOUT filtering out the module landing page ===
  error count: 1
  files written:
    (none)

=== MAML export WITH the documented CommandHelp filter ===
  error count: 0
  files written:
    \maml-filtered\ScratchModule\ScratchModule-help.xml

The markdown path behaves differently, and the entry says so. Update-MarkdownCommandHelp
rejects the landing page loudly ('…\ScratchModule.md' is not a CommandHelp file.) and
converts the rest anyway. But Import-MarkdownCommandHelp accepts it silently, returns a
CommandHelp object titled after the module, and Export-MarkdownCommandHelp writes it back
as an empty cmdlet document with the landing page's {{ Update Download Link }} placeholders
embedded as malformed YAML. Silent corruption rather than an abort.

The skip-without--Force hazard

--- mutate one exported file, then export again WITHOUT -Force ---
  WARNING/OUTPUT: 'Get-ScratchWidget' exists, skipping. Use -Force to overwrite.
  WARNING/OUTPUT: 'New-ScratchWidget' exists, skipping. Use -Force to overwrite.
  WARNING/OUTPUT: 'Remove-ScratchWidget' exists, skipping. Use -Force to overwrite.
  sentinel still present (file was skipped): True

Confirmed: warning only, nothing written, success returned.

Documents the build cannot convert

Update-MarkdownCommandHelp resolves each document's command in the current session. Without
the module imported it fails with a message that is only the command name:

  error count: 3
  Message  : 'Get-ScratchWidget'
  ErrorId  : FailedToImportMarkdown,Microsoft.PowerShell.PlatyPS.UpdateMarkdownHelpCommand
  Category : InvalidOperation / CommandNotFoundException
  schema line after the failed run:
    schema: 2.0.0

Nothing is written and the file stays on 0.14.x. This is why an orphaned document — one for a
command the module no longer exports — never converts, and why Measure-PlatyPSMarkdown
reporting V1Schema after a build is the detection step in the entry.

Also verified: Update-MarkdownModuleFile cannot refresh a landing page on its own — it
requires the -CommandHelp objects the page indexes (Cannot process command because of one or more missing mandatory parameters: CommandHelp.). The entry says to leave the page alone and
let the build replace it.

Test Plan

  • ./build.ps1 -Task TestTests Passed: 471, Failed: 0, Skipped: 2 (unchanged baseline)
  • Documentation-only change; no module source touched
  • Checked against .markdownlint.json — no trailing whitespace, no hard tabs, single
    trailing newline; the only lines over 100 characters are unbreakable link lines,
    matching the existing entries in the same file

Breaking Changes

None. Documentation only.

🤖 Generated with Claude Code

https://claude.ai/code/session_01MuBy4d575f3TQf4c2FmVdA

Add a migration entry covering how a consumer converts a committed docs/
tree from the platyPS 0.14.x schema to the Microsoft.PowerShell.PlatyPS
1.x schema, plus a Quick Start bullet linking to it.

The headline finding is that most consumers need no conversion step at
all: the GenerateMarkdown task already runs Update-MarkdownCommandHelp
over every existing command document, so an ordinary 1.0.0 build rewrites
a 0.14.x tree in place. The entry reframes the work as reading the diff
rather than running a one-shot, and documents the manual path for the
cases where a build cannot do it.

Every claim was verified against Microsoft.PowerShell.PlatyPS 1.0.3 using
a throwaway module whose 0.14.x markdown was generated by platyPS 0.14.2
in a separate process, then hand-edited so content loss would be visible.

Closes #154

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MuBy4d575f3TQf4c2FmVdA
Copilot AI lite review requested due to automatic review settings August 26, 2026 19:16

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@github-actions

Copy link
Copy Markdown

Test Results

    4 files  ±0    740 suites  ±0   3m 51s ⏱️ - 1m 8s
  472 tests ±0    470 ✅ ±0   2 💤 ±0  0 ❌ ±0 
1 892 runs  ±0  1 831 ✅ ±0  61 💤 ±0  0 ❌ ±0 

Results for commit 0668cb7. ± Comparison against base commit 9177803.

@tablackburn
tablackburn merged commit 495b57e into main Aug 26, 2026
9 checks passed
@tablackburn
tablackburn deleted the docs/154-consumer-docs-schema-conversion branch August 26, 2026 21:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

PlatyPS 2e: document the docs/ schema conversion for consumers

2 participants