Submodule Management & Automation
Submodule management and automation
This page covers the CI/automation side of submodule management: the GitHub Actions workflows, the .megadoc/ fallback scripts, and how to recover when the automation fails. For the local developer workflow (clone, init, update, worktree interaction), see Submodules guide.
Quick navigation
- Overview
- Workflows and triggers
- Step-by-step: onboarding a new submodule
- The .megadoc/ fallback system
- Best practices
- Troubleshooting
- Resources and next steps
Overview
MEGADOC aggregates ~74 git submodules into a single MkDocs site via the mkdocs-monorepo-plugin. Two GitHub Actions workflows keep this safe at scale:
| Workflow file | Purpose |
|---|---|
.github/workflows/submodule-adder.yml | Reads submodules_source.txt, opens a PR that adds any missing submodules. |
.github/workflows/validate-submodules.yml | Runs .megadoc/scripts/validate-submodules.py and apply-fallbacks.py; auto-files issues against non-compliant repos. |
Workflows and triggers
submodule-adder.ymlis manual only (on: workflow_dispatch:). Run it from the GitHub UI: Actions → Load Submodules → Run workflow. It readssubmodules_source.txt, diffs against.gitmodules, and runsgit submodule addfor each new entry.validate-submodules.ymltriggers onworkflow_dispatchand onpushtomainwhen any of.gitmodules,.megadoc/scripts/apply-fallbacks.py,.megadoc/scripts/validate-submodules.py,.megadoc/README.md, or.megadoc/templates/issue-template.mdchange. There is no PR trigger and no scheduled cron. It enforces the requiredmkdocs.yml+docs/+docs/index.mdstructure on every submodule and creates issues in upstream repos missing the structure.
Step-by-step: onboarding a new submodule
-
Create a feature branch / worktree from
main. -
Append the repo slug to
submodules_source.txt— one<org>/<repo>per line, no scheme, no path, no branch. Example:optum-tech-compute/ohemr-ansible-role-example -
Commit using a conventional-commits message:
git add submodules_source.txt git commit -m "chore(submodules): add ohemr-ansible-role-example" git push -u origin <branch> -
Open a PR with the
submodules_source.txtchange, then trigger the workflow manually from Actions → Load Submodules → Run workflow. The job will rungit submodule addfor each new entry and push the commit back onto the PR branch. -
After the next push to
main(or a manualworkflow_dispatch),validate-submodules.ymlruns against the new submodule. If it lacks the required structure, an issue is auto-filed in the upstream repo and the.megadoc/fallback layer keeps the build green. -
Review the rendered docs locally:
git submodule update --init --recursive mkdocs build --strict mkdocs serve -
Merge the PR once
mkdocs build --strictand thedocs-quality-check.ymlchecks are green.
The .megadoc/ fallback system
When a submodule has not yet adopted the required documentation structure, the fallback layer keeps the MEGADOC build green and the issue tracked.
| Path | Role |
|---|---|
.megadoc/scripts/validate-submodules.py | Scans submodules/, writes a JSON report of missing files, and (on CI) opens GitHub issues. |
.megadoc/scripts/apply-fallbacks.py | Reads the report, writes minimal mkdocs.yml / docs/index.md shims under .megadoc/fallbacks/. |
.megadoc/fallbacks/<submodule>/ | Generated, build-time-only stand-ins; the nav: includes resolve to these when the real ones are absent. |
Run the pair locally before pushing a submodule bump:
python3 .megadoc/scripts/validate-submodules.py --output megadoc-validation.json
python3 .megadoc/scripts/apply-fallbacks.py --report megadoc-validation.json
mkdocs build --strict
The --output / --report flags match the contract used by .github/workflows/validate-submodules.yml in CI.
Best practices
- Default branch tracking is implicit; if you need a non-default branch, edit
.gitmodulesafter the adder workflow runs and commit the change. - Open one submodule per PR; mass-adding them makes review and bisect painful.
- The adder workflow constructs HTTPS clone URLs; do not paste SSH URLs or full URLs into
submodules_source.txt— only<org>/<repo>slugs. - Use conventional-commits scope
submodules(e.g.chore(submodules): bump ohemr-ansible-role-odb) sosemantic-releaseand the org ruleset accept the message. - Re-run
validate-submodules.pyafter every bump; submodules drift.
Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
submodule-adder.yml PR is empty | Entry already present in .gitmodules | Inspect .gitmodules; remove the duplicate from submodules_source.txt. |
mkdocs build fails with "could not include submodules/<x>/mkdocs.yml" | Submodule not initialized | git submodule update --init --recursive |
validate-submodules.yml opens an issue in your repo | Submodule is missing docs/, mkdocs.yml, or docs/index.md | Land the missing files in the upstream repo, or rely on .megadoc/fallbacks/ until you can. |
| Submodule appears empty in a worktree | .git/modules/ not yet populated for that worktree | Run git submodule update --init --recursive inside the worktree root. |
submodule-adder.yml cannot push | Branch protection / org ruleset blocks workflow commits | Have a maintainer rerun under a token with the appropriate ruleset bypass; do not disable the rule. |
Resources and next steps
- Submodules guide — local developer workflow (clone, init, update, worktrees).
- Contributing overview — see the "Working with Submodules" section.
.megadoc/scripts/validate-submodules.pyand.megadoc/scripts/apply-fallbacks.py— the canonical implementation of the fallback layer..github/workflows/submodule-adder.ymland.github/workflows/validate-submodules.yml— the CI side of this workflow.