Skip to content

Export WinUI Gallery samples as a catalog/windows-samples.json manifest - #2226

Draft
Niels Laute (niels9001) wants to merge 1 commit into
mainfrom
niels9001-sample-catalog-manifest
Draft

Export WinUI Gallery samples as a catalog/windows-samples.json manifest#2226
Niels Laute (niels9001) wants to merge 1 commit into
mainfrom
niels9001-sample-catalog-manifest

Conversation

@niels9001

Copy link
Copy Markdown
Collaborator

Why

microsoft/windows-samples aggregates standalone projects via one Samples/<Name>/sample.yml
each, generating catalog/samples.json for agents and a browser gallery. WinUI Gallery's ~120
samples are different: they're pages embedded in one app
(WinUIGallery/Samples/<UniqueId>/), and an authoritative inventory of them already exists at
WinUIGallery/SampleSupport/Data/ControlInfoData.json
(consumed today by the app itself and by WinUIGallery.SourceGenerator).

This PR makes that existing inventory exportable into a future federated windows-samples
catalog without creating ~120 duplicate sample.yml files. ControlInfoData.json stays the
single source of truth; a small generator derives and validates everything else.

What's here

  • tools/CatalogExporter – a plain, platform-agnostic (no WinUI/Windows App SDK) console
    tool + library that:
    • Reads ControlInfoData.json (Title, Subtitle/Description, Docs, Tags,
      RelatedControls – all already present in the JSON/schema) and the
      WinUIGallery/Samples/<UniqueId>/ folders.
    • Derives ids, group, source file paths, snippet files, and interactive scenarios (one per
      controls:ControlExample element with a SampleDefinition="..." snippet reference).
    • Validates: unique ids, a case-exact <UniqueId>Page.xaml per item, resolvable
      RelatedControls/Catalog.RelatedSamples references, and existing SampleDefinition
      snippets — failing loudly (CatalogValidationException) instead of guessing.
    • Serializes deterministically (sorted samples, LF line endings, null instead of []/""
      for anything with no source data).
    • dotnet run --project tools/CatalogExporter -- generate regenerates the manifest;
      ... -- check verifies it without writing anything (used in CI).
  • catalog/windows-samples.json – the generated manifest (120 samples), plus
    catalog/windows-samples.schema.json (JSON Schema draft-07 contract) and
    catalog/README.md (design rationale, field mapping table, inclusion/exclusion rules,
    regeneration instructions).
  • A small, optional Catalog override block added to ControlInfoDataSchema.json
    (Exclude / Aliases / RelatedSamples) for the rare item that needs to diverge from what's
    auto-derived. Demonstrated (not invented) on two real entries: Button and ScratchPad each
    get Catalog.Aliases in ControlInfoData.json. This block is read only by the exporter — the
    running app is unaffected.
  • tests/WinUIGallery.CatalogExporter.Tests – plain MSTest (no WinUI dependency, so it runs
    with a plain dotnet test, unlike the packaged WinUIGallery.UnitTests/UITests) covering:
    normalization (optional fields omitted, not guessed), determinism, duplicate-id detection,
    missing-folder detection, case-mismatch detection, broken related-reference detection, missing
    snippet detection, Catalog.Exclude, Catalog.Aliases/RelatedSamples merging, and — against
    the real repository data — that the committed manifest is not stale.
  • Both new projects are wired into WinUIGallery.slnx, and .pipelines/azure-pipelines.yml
    gained one fast dotnet test step so a stale/hand-edited manifest fails CI.

Design choices

  • No commit-SHA pinning. The manifest records repository.defaultBranch, not a hash, and is
    regenerated whenever samples change.
  • Manifest-level defaults carry the facts shared by every entry (MIT, C#, WinUI 3, Windows
    App SDK, embedded-gallery-page kind) instead of repeating them ~120 times.
  • Source-qualified ids ("{owner}/{repo}#{uniqueId}") so aggregation across repositories in
    windows-samples can't collide.
  • Optional/unknown fields are omitted rather than filled with guesses.

Validation

dotnet run --project tools/CatalogExporter -- generate   # 120 samples
dotnet run --project tools/CatalogExporter -- check       # up to date
dotnet test tests/WinUIGallery.CatalogExporter.Tests      # 12/12 passed
dotnet restore WinUIGallery.slnx                           # all 6 projects restore cleanly

No changes to the running app's behavior; ControlInfoDataSchema.json's new Catalog block is
additive and ignored by the app today (mirroring how RelatedControls already sits unused in the
schema/JSON).

Opened as draft: a follow-up PR in microsoft/windows-samples will import this manifest into its
own catalog/samples.json aggregation.

- Add tools/CatalogExporter: a small, platform-agnostic console tool/library
  that derives a machine-readable manifest from the existing
  WinUIGallery/SampleSupport/Data/ControlInfoData.json source of truth plus
  the on-disk WinUIGallery/Samples/<UniqueId>/ folders, validates it
  (unique ids, case-exact referenced paths, resolvable RelatedControls /
  Catalog.RelatedSamples references, existing SampleDefinition snippets),
  and serializes it deterministically.
- Generate catalog/windows-samples.json (120 samples) plus
  catalog/windows-samples.schema.json (JSON Schema contract) and
  catalog/README.md (design rationale + regeneration/check instructions).
- Extend ControlInfoDataSchema.json with an optional, additive Catalog
  override block (Exclude/Aliases/RelatedSamples), demonstrated on the
  Button and ScratchPad entries in ControlInfoData.json. Everything else
  is derived, so no per-item sample.yml duplication is introduced.
- Add tests/WinUIGallery.CatalogExporter.Tests (plain MSTest, no WinUI
  dependency) covering normalization, determinism, path/reference
  validation, and stale-output detection against the real repository data.
- Wire both new projects into WinUIGallery.slnx and add a fast
  'dotnet test' step to azure-pipelines.yml so a stale manifest fails CI.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
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.

1 participant