Skip to main content

Composite documentation sections

Some product families span multiple Git repositories but should read as one area on the published site. The docs portal supports this with composite sections: federated ownership, centralized publishing.

Problem

The default portal model maps one registry entry → one workflow repository → one mirror folder → one navbar section. That works for standalone workflows like Superbuild, but not for ecosystems such as A2C, where:

  • a2c-workflow owns core method and engine documentation
  • a2c-pre-commit-hooks owns hook package documentation
  • a2c-vscode-extension owns extension documentation

Copying sibling docs into a2c-workflow would violate ownership and create duplication. Separate top-level navbar tabs would fragment the reader experience.

Chosen model

PrincipleImplementation
Single published entry pointOne Docusaurus plugin and navbar item (/a2c/)
Distributed ownershipEach repo authors docs in its own docs/ tree
Build-time aggregationPortal sync mirrors each contributor into a subfolder of docs-a2c/
Unified navigationRegistry sidebar_composition groups mirrored pages by contributor category
Source identity preservedDocusaurus editUrl routes maintainers to the correct upstream repository
┌─ a2c-workflow ─────────────┐ ┌─ a2c-pre-commit-hooks ────┐ ┌─ a2c-vscode-extension ──┐
│ docs/ (core) │ │ docs/ (hooks) │ │ docs/ (extension) │
│ sync_id: a2c │ │ sync_id: a2c-pre-commit… │ │ sync_id: a2c-vscode-ext…│
└──────────────┬──────────────┘ └─────────────┬──────────────┘ └────────────┬────────────┘
│ │ │
└───────────────────────────────┼──────────────────────────────┘

┌────── docs-portal /a2c/ ──────┐
│ intro.md (portal-owned) │
│ workflow/… (core mirror) │
│ pre-commit-hooks/… │
│ vscode-extension/… │
└────────────────────────────────┘

Registry contract

Composite sections set section_type: composite in workflows/registry.yaml:

FieldPurpose
contributors[]Upstream repos, each with sync_id, gitlab_project, target_subdir
sidebar_composition[]Sidebar blocks: portal intro doc + category per contributor
target_dir, sidebar_file, …Same as single-repo sections (one mirror root, one sidebar file)

Each contributor repository ships docs/workflow-manifest.yaml with:

  • sync_id — matches registry contributor (used by CI WORKFLOW_SYNC_ID)
  • section_id — parent composite section (a2c)
  • sidebar_order — slugs within that contributor's mirror subfolder

Legacy manifests may still use workflow_id when it equals the core contributor sync_id.

Sync behaviour

  • python scripts/sync_workflow.py <sync_id> syncs one contributor and rebuilds the full composite sidebar (loading sibling manifests from local clones or CI fetch).
  • python scripts/sync_all_workflows.py expands composite sections into all contributors.
  • Core contributor (target_subdir: "") prunes stale files at docs-a2c/ root but never deletes sibling contributor subfolders.
  • Contributor subfolders (pre-commit-hooks/, vscode-extension/) prune independently.

CI-generated companion assets

Some contributors build documentation assets in CI without committing them to git (for example ExTester UI screenshots). Declare ci_artifact_overlay in the contributor manifest:

ci_artifact_overlay:
job_name: test:integration:screenshots
required_in_ci: true
paths:
- docs/assets/extension/
- docs/extension-screenshots.md

The upstream pipeline forwards WORKFLOW_SYNC_PARENT_PIPELINE_ID and WORKFLOW_SYNC_ARTIFACT_JOB to docs-portal. Sync downloads the job artifact archive, overlays the clone, then mirrors markdown and companion_dirs into the portal repo so npm run build includes the PNGs.

Automated commits use chore(sync): Update mirrored docs for a2c (<sync_id>).

Onboarding a new A2C contributor

  1. Add docs + manifest in the new repository (templates/workflow-manifest-contributor.yaml).
  2. Add docs/portal-integration.md and docs/navigation-meta.md.
  3. Enable workflow-docs:contract + trigger:docs-portal in that repo's CI with a unique WORKFLOW_SYNC_ID.
  4. Register a new contributors[] entry and sidebar_composition category in workflows/registry.yaml.
  5. Run first sync from docs-portal and verify npm run build.

When to use composite vs standalone section

Use compositeUse standalone section
Repos are facets of one product family readers expect togetherRepo is an independent workflow product (e.g. Superbuild)
Docs cross-reference heavily within the familyMinimal cross-navigation with siblings
Separate navbar tab would confuse discoveryDistinct audience and lifecycle