Megadoc Core Repository Patterns
Comprehensive guide for maintaining the ohemr-epic-megadoc monorepo - managing the MkDocs configuration, monorepo plugin patterns, fallback mechanisms, and submodule integration.
Megadoc Core Repository Patterns
Overview
This instruction applies to maintainers of the ohemr-epic-megadoc monorepo - the parent repository that aggregates documentation from dozens of submodule repositories into a unified MkDocs site.
Target audience: Platform SRE team, megadoc maintainers, documentation leads.
Critical Concept: The Monorepo Pattern
Megadoc is NOT a traditional MkDocs site:
- It doesn't contain all documentation directly
- It includes documentation from Git submodules using the monorepo plugin
- Each submodule provides a stub
mkdocs.ymlthat gets merged into the parent nav
Analogy: Megadoc is the book binder; submodules are the chapters.
Why This Matters
Consistency: One theme, one plugin set, one build process → uniform experience across 100+ repos
Scalability: Add new repo = add one submodule + one !include line (wildcards enable bulk inclusion)
Ownership: Each team owns their docs in their repo; megadoc team owns presentation layer
Safety: Fallback mechanism prevents build failures when submodules lack documentation
Repository Structure
ohemr-epic-megadoc/
├── mkdocs.yml # Main configuration (this is where magic happens)
├── docs/ # Core megadoc content (landing pages, guides)
│ ├── index.md # Site home page
│ ├── contributing.md # How to contribute to megadoc
│ └── architecture/ # Megadoc system documentation
├── submodules/ # Git submodules (referenced repositories)
│ ├── ohemr-ansible-role-*/ # Ansible roles (wildcard pattern target)
│ ├── ohemr-terraform-module-*/ # Terraform modules
│ ├── ohemr-action-library/ # GitHub Actions
│ └── ... # 100+ repositories
├── .megadoc/ # Megadoc tooling and automation
│ ├── fallbacks/ # Auto-generated stubs for repos without docs
│ ├── scripts/
│ │ ├── validate-submodules.py # Checks for missing/invalid docs
│ │ ├── apply-fallbacks.py # Generates placeholder docs
│ │ └── update-submodules.sh # Updates all submodules to latest
│ └── templates/
│ ├── mkdocs.yml.template # Template for submodule stubs
│ └── issue-template.md # GitHub issue template for missing docs
├── .github/
│ └── workflows/
│ ├── build-docs.yml # Build and deploy megadoc site
│ ├── validate-docs.yml # Pre-merge validation
│ └── generate-issues.yml # Auto-create issues for missing docs
└── README.md
Main mkdocs.yml Configuration
Site Metadata
site_name: EPIC Platform Documentation
site_url: https://docs.epic.optum.com
site_description: Unified documentation for EPIC platform infrastructure, tools, and services
repo_url: https://github.com/optum-tech-compute/ohemr-epic-megadoc
repo_name: optum-tech-compute/ohemr-epic-megadoc
edit_uri: edit/main/docs
These settings apply to the entire megadoc site - submodules override repo_url, repo_name, and edit_uri for their pages.
Theme Configuration
theme:
name: material
palette:
# Scheme toggle (light/dark mode)
- media: '(prefers-color-scheme: light)'
scheme: default
primary: indigo
accent: indigo
toggle:
icon: material/brightness-7
name: Switch to dark mode
- media: '(prefers-color-scheme: dark)'
scheme: slate
primary: indigo
accent: indigo
toggle:
icon: material/brightness-4
name: Switch to light mode
features:
- navigation.instant # Fast page loads (SPA-like)
- navigation.tracking # URL updates on scroll
- navigation.tabs # Top-level tabs
- navigation.sections # Collapsible sections
- navigation.expand # Expand all sections by default
- navigation.indexes # Section index pages
- toc.follow # TOC highlights current section
- toc.integrate # TOC in left sidebar
- search.suggest # Search suggestions
- search.highlight # Highlight search terms
- content.code.copy # Copy button on code blocks
- content.action.edit # Edit page button
Theme is applied globally - submodules inherit this theme automatically.
Plugins Configuration
plugins:
- search:
lang: en
separator: '[\s\-,:!=\[\]()"/]+|\.(?!\d)|&[lg]t;|(?!\b)(?=[A-Z][a-z])'
- monorepo:
enabled: !ENV [MONOREPO_ENABLED, true]
- tags:
tags_file: tags.md
- git-revision-date-localized:
enable_creation_date: true
type: timeago
Critical: The monorepo plugin enables !include functionality - this is the lynch pin.
Monorepo Plugin Deep Dive
What it does:
- Finds
!includedirectives in your navigation - Loads referenced
mkdocs.ymlfiles from submodules - Merges submodule navigation into parent site navigation
- Preserves submodule context (repo URLs, edit links, etc.)
Example:
nav:
- Home: index.md
- Ansible Roles:
- Base OS Config: '!include submodules/ohemr-ansible-role-base-os-config/mkdocs.yml'
Result: The navigation structure from ohemr-ansible-role-base-os-config/mkdocs.yml appears under "Ansible Roles".
Markdown Extensions
markdown_extensions:
# Python Markdown
- abbr # Abbreviations
- admonition # Callouts
- attr_list # Add HTML attributes
- def_list # Definition lists
- footnotes # Footnote references
- md_in_html # Markdown in HTML
- toc:
permalink: true # Add anchor links to headings
# PyMdown Extensions
- pymdownx.arithmatex:
generic: true # Math support
- pymdownx.betterem:
smart_enable: all # Better emphasis handling
- pymdownx.caret # Superscript
- pymdownx.mark # Highlighting
- pymdownx.tilde # Subscript, strikethrough
- pymdownx.details # Collapsible details
- pymdownx.emoji:
emoji_index: !!python/name:material.extensions.emoji.twemoji
emoji_generator: !!python/name:material.extensions.emoji.to_svg
- pymdownx.highlight:
anchor_linenums: true # Anchor line numbers
line_spans: __span # Line highlighting
pygments_lang_class: true
- pymdownx.inlinehilite # Inline code highlighting
- pymdownx.keys # Keyboard keys
- pymdownx.snippets # Include file snippets
- pymdownx.superfences: # Fenced code blocks
custom_fences:
- name: mermaid
class: mermaid
format: !!python/name:pymdownx.superfences.fence_code_format
- pymdownx.tabbed:
alternate_style: true # Content tabs
- pymdownx.tasklist:
custom_checkbox: true # Task lists
Extensions are applied globally - all submodule content gets these capabilities.
Navigation Structure and !include
Basic !include Pattern
nav:
- Home: index.md
- Getting Started: contributing.md
- Infrastructure:
- Terraform Modules:
- VPC Module: '!include submodules/ohemr-terraform-module-vpc/mkdocs.yml'
- EKS Module: '!include submodules/ohemr-terraform-module-eks/mkdocs.yml'
- Ansible Roles:
- Base OS: '!include submodules/ohemr-ansible-role-base-os-config/mkdocs.yml'
- App Install: '!include submodules/ohemr-ansible-role-application-and-agents/mkdocs.yml'
- GitHub Actions:
- Action Library: '!include submodules/ohemr-action-library/mkdocs.yml'
Each !include:
- References a submodule's
mkdocs.yml - Loads that submodule's navigation structure
- Merges it into the parent navigation at that position
- Preserves submodule's repo context for edit links
Wildcard !include Pattern (THE POWER MOVE)
One line includes dozens of repos:
nav:
- Ansible Roles: '*include submodules/ohemr-ansible-role-*/mkdocs.yml'
What happens:
- Plugin discovers all paths matching
submodules/ohemr-ansible-role-*/mkdocs.yml - Loads each matching
mkdocs.yml - Creates navigation tree sorted alphabetically by
site_name
Result:
Ansible Roles
├── Application and Agents
├── Base OS Config
├── Security Compliance
├── Monitoring Setup
└── (100 more roles...)
Why this is critical:
- Scalability: 100 repos = 1 configuration line
- Maintenance: Add new repo = add Git submodule (zero config changes)
- Consistency: All repos appear in navigation automatically
- DRY principle: Don't repeat yourself for every new repo
Multiple Wildcard Patterns
nav:
- Home: index.md
- Terraform Modules: '*include submodules/ohemr-terraform-module-*/mkdocs.yml'
- Ansible Roles: '*include submodules/ohemr-ansible-role-*/mkdocs.yml'
- GitHub Actions: '*include submodules/ohemr-action-*/mkdocs.yml'
- Documentation: '*include submodules/ohemr-doc-*/mkdocs.yml'
Result: Four navigation sections, each auto-populated from matching repositories.
Mixed Pattern (Explicit + Wildcard)
nav:
- Home: index.md
- Featured Modules:
- VPC Module: '!include submodules/ohemr-terraform-module-vpc/mkdocs.yml'
- EKS Module: '!include submodules/ohemr-terraform-module-eks/mkdocs.yml'
- All Terraform Modules: '*include submodules/ohemr-terraform-module-*/mkdocs.yml'
Use case: Highlight important repos explicitly, then show complete list.
Submodule Management
Adding a New Submodule
# Add Git submodule
git submodule add https://github.com/optum-tech-compute/ohemr-ansible-role-example submodules/ohemr-ansible-role-example
# Commit submodule reference
git add .gitmodules submodules/ohemr-ansible-role-example
git commit -m "Add ohemr-ansible-role-example submodule"
If using wildcard pattern: No mkdocs.yml changes needed!
If using explicit includes: Add !include line to nav.
Updating Submodules
# Update single submodule to latest
cd submodules/ohemr-ansible-role-example
git pull origin main
cd ../..
git add submodules/ohemr-ansible-role-example
git commit -m "Update ohemr-ansible-role-example submodule"
# Update all submodules to latest
git submodule update --remote
git add submodules/
git commit -m "Update all submodules to latest"
Automation: .megadoc/scripts/update-submodules.sh updates all submodules and creates PR.
Removing a Submodule
# Remove submodule
git submodule deinit -f submodules/ohemr-ansible-role-example
git rm -f submodules/ohemr-ansible-role-example
rm -rf .git/modules/submodules/ohemr-ansible-role-example
# If using explicit includes, remove from nav
# Edit mkdocs.yml and remove the !include line
git commit -m "Remove ohemr-ansible-role-example submodule"
Fallback Mechanism
What Are Fallbacks?
Problem: Not every repository has proper documentation yet. Solution: Auto-generate placeholder documentation to prevent build failures.
Fallback Structure
.megadoc/fallbacks/ohemr-ansible-role-example/
├── mkdocs.yml # Minimal stub configuration
└── docs/
└── index.md # Placeholder content
How Fallbacks Work
-
Validation (
.megadoc/scripts/validate-submodules.py):- Check each submodule for
mkdocs.ymlanddocs/index.md - Identify repositories missing documentation
- Check each submodule for
-
Generation (
.megadoc/scripts/apply-fallbacks.py):- Create fallback stub from template
- Include repo name, link to GitHub, placeholder content
- Log fallback creation
-
Build Process:
- MkDocs build tries to include submodule's mkdocs.yml
- If missing, monorepo plugin falls back to
.megadoc/fallbacks/repo-name/mkdocs.yml - Site builds successfully with placeholder content
-
Issue Creation (
.github/workflows/generate-issues.yml):- GitHub Action detects repos using fallbacks
- Creates issue in submodule repo: "Add megadoc-compliant documentation"
- Provides setup instructions and links to templates
Fallback Templates
.megadoc/templates/mkdocs.yml.template:
site_name: { { repo_name } }
repo_url: https://github.com/optum-tech-compute/{{ repo_name }}
repo_name: optum-tech-compute/{{ repo_name }}
edit_uri: edit/main/docs
nav:
- Home: index.md
.megadoc/templates/index.md.template:
---
title: { { repo_name } }
description: Documentation for {{ repo_name }} (placeholder)
owner: unknown
doc_type: concept
lifecycle_status: experimental
last_reviewed: { { today } }
tags:
- placeholder
- needs-docs
---
# {{ repo_name }}
**This is placeholder documentation auto-generated by megadoc.**
This repository does not yet have megadoc-compliant documentation.
## Getting Started
To add proper documentation to this repository:
1. Create `mkdocs.yml` in repository root
2. Create `docs/index.md` with content
3. Follow the [megadoc submodule patterns guide](...)
## Repository
- **GitHub**: [{{ repo_name }}](https://github.com/optum-tech-compute/{{ repo_name }})
- **Status**: Missing documentation
- **Action Required**: Add mkdocs.yml and docs/ folder
For help, contact @epic-platform-sre or see the megadoc contributing guide.
Monitoring Fallbacks
# List all fallbacks
ls .megadoc/fallbacks/
# Check which repos use fallbacks
python .megadoc/scripts/validate-submodules.py --list-fallbacks
Goal: Zero fallbacks - every repo should have real documentation.
Validation and CI/CD
Pre-Merge Validation
.github/workflows/validate-docs.yml runs on every PR:
name: Validate Documentation
on:
pull_request:
paths:
- 'mkdocs.yml'
- 'docs/**'
- 'submodules/**'
- '.megadoc/**'
jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
submodules: recursive # Fetch all submodules
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Install dependencies
run: |
pip install mkdocs mkdocs-material mkdocs-monorepo-plugin
- name: Validate submodule documentation
run: python .megadoc/scripts/validate-submodules.py
- name: Build documentation
run: mkdocs build --strict
- name: Check for broken links
run: python .megadoc/scripts/check-links.py
Checks:
- Submodule documentation exists and is valid
- Site builds without errors (
--strictmode) - No broken internal links
- Navigation structure is correct
Build and Deploy
.github/workflows/build-docs.yml runs on merge to main:
name: Build and Deploy Docs
on:
push:
branches: [main]
schedule:
- cron: '0 2 * * *' # Daily at 2am (catch submodule updates)
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
submodules: recursive
fetch-depth: 0 # Full history for git-revision-date plugin
- name: Update submodules to latest
run: git submodule update --remote
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Install dependencies
run: |
pip install mkdocs mkdocs-material mkdocs-monorepo-plugin \
mkdocs-git-revision-date-localized-plugin
- name: Apply fallbacks
run: python .megadoc/scripts/apply-fallbacks.py
- name: Build site
run: mkdocs build
- name: Deploy to GitHub Pages
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./site
Deployment flow:
- Fetch all submodules recursively
- Update submodules to latest commits
- Apply fallbacks for repos without docs
- Build site
- Deploy to GitHub Pages
Maintenance Tasks
Weekly: Review Fallbacks
# Generate fallback report
python .megadoc/scripts/validate-submodules.py --report > fallback-report.txt
# Review report and identify repos needing documentation
# Create GitHub issues in those repos
Monthly: Update Submodules
# Update all submodules to latest
git submodule update --remote
# Test build
mkdocs build --strict
# Commit if successful
git add submodules/
git commit -m "chore: update all submodules to latest"
git push
Quarterly: Theme and Plugin Updates
# Update dependencies
pip install --upgrade mkdocs mkdocs-material mkdocs-monorepo-plugin
# Test build
mkdocs build --strict
# If successful, update requirements.txt
pip freeze > requirements.txt
git add requirements.txt
git commit -m "chore: update mkdocs dependencies"
As Needed: Navigation Restructuring
Process:
- Create feature branch
- Update
nav:inmkdocs.yml - Test locally:
mkdocs serve - Verify all sections appear correctly
- Create PR and get team review
- Merge and monitor build
Troubleshooting
Submodule Not Appearing in Navigation
Symptoms: Added submodule, but docs don't show up in site
Diagnosis:
# Check submodule exists
ls submodules/repo-name/
# Check for mkdocs.yml
cat submodules/repo-name/mkdocs.yml
# Check for docs/index.md
cat submodules/repo-name/docs/index.md
# Try building locally
mkdocs build --strict
Solutions:
- Ensure
mkdocs.ymlhas required fields (site_name, repo_url, repo_name, edit_uri) - Verify
docs/index.mdexists - Check navigation pattern in parent
mkdocs.ymlincludes this repo - If using wildcards, ensure repo name matches pattern
Build Fails with "Nav section not found"
Symptoms: mkdocs build fails with navigation error
Diagnosis:
- Check error message for specific
!includepath - Verify that submodule path exists
- Check if submodule
mkdocs.ymlhas syntax errors
Solutions:
# Validate specific submodule mkdocs.yml
cd submodules/problematic-repo
mkdocs build --strict
# Check YAML syntax
python -c "import yaml; yaml.safe_load(open('mkdocs.yml'))"
Wildcard Pattern Not Matching Expected Repos
Symptoms: Wildcard !include matches too many/too few repos
Diagnosis:
# Test glob pattern
ls submodules/ohemr-ansible-role-*/mkdocs.yml
# Count matches
ls submodules/ohemr-ansible-role-*/mkdocs.yml | wc -l
Solutions:
- Adjust wildcard pattern to be more specific
- Use multiple wildcard patterns for different categories
- Switch to explicit includes if wildcard is too broad
Edit Links Point to Wrong Branch
Symptoms: "Edit on GitHub" links lead to 404
Diagnosis:
- Check submodule's
edit_uriin theirmkdocs.yml - Verify default branch name (main vs master vs develop)
Solutions:
# In submodule's mkdocs.yml
edit_uri: edit/main/docs # For main branch
edit_uri: edit/develop/docs # For develop branch
Best Practices
DO
- ✅ Use wildcard patterns for categories with many repos
- ✅ Keep parent mkdocs.yml focused on structure, not content
- ✅ Apply fallbacks automatically to prevent build failures
- ✅ Update submodules regularly (daily/weekly)
- ✅ Test locally before pushing navigation changes
- ✅ Document why repos are organized in specific nav sections
- ✅ Monitor fallback count - work toward zero fallbacks
DON'T
- ❌ Put actual content in parent mkdocs.yml nav (use submodules)
- ❌ Allow build failures due to missing submodule docs
- ❌ Update submodules without testing build
- ❌ Make breaking changes to theme without testing all submodules
- ❌ Override submodule metadata in parent config
- ❌ Forget to initialize submodules after cloning repo
Summary
ohemr-epic-megadoc monorepo:
- Aggregates documentation from 100+ submodule repositories
- Uses monorepo plugin's
!includedirective to merge navigation - Wildcard patterns enable scaling (1 line = 100 repos)
- Fallback mechanism prevents build failures
- Unified theme and plugins ensure consistency
- Automated validation and deployment pipelines
Key maintainer responsibilities:
- Manage parent
mkdocs.ymlnavigation structure - Add/update/remove submodules as repos evolve
- Monitor and reduce fallback usage
- Update theme and plugins regularly
- Ensure builds remain stable as submodules change
- Support teams adding documentation to their repos
The result: A unified, scalable, consistent documentation site that grows automatically as new repositories are added.
Related Assets
Megadoc Submodule Documentation Patterns
Comprehensive guide for creating megadoc-compliant documentation in submodule repositories that integrate with the ohemr-epic-megadoc monorepo system.
Owner: epic-platform-sre
Megadoc Architecture and Documentation Standards
Comprehensive guide for ohemr-epic-megadoc architecture, documentation structure, and LLM-generated content standards
Owner: epic-platform-sre
thoth
Documentation architecture, MkDocs monorepo builds, and Diataxis enforcement
Owner: epic-platform-sre
Create Megadoc-Compliant Content
Generate high-quality, megadoc-compliant documentation pages with proper front matter, Diátaxis categorization, and style guide adherence for any documentation need.
Owner: epic-platform-sre
Generate Megadoc Stub Configuration
Creates megadoc-compliant stub mkdocs.yml and initial docs/ structure for a repository that will be included as a submodule in ohemr-epic-megadoc.
Owner: epic-platform-sre
Troubleshoot Megadoc Issues
Diagnostic guide for resolving common megadoc integration problems including missing documentation, build failures, broken links, navigation issues, and monorepo plugin errors.
Owner: epic-platform-sre

