Skip to content

File Synchronization

The file sync workflow at .github/workflows/sync-managed-files.yml runs as a parallel job alongside settings enforcement, using the REPO_SYNC_TOKEN (Contents R/W, Issues R/W, Pull Requests R/W, Metadata Read).

It skips execution when running on the source repository itself (docs-control), since the canonical files already live here.

The workflow iterates the managed_files.files array from the central config. For each entry, it fetches the canonical content from docs-control and compares it against the downstream copy. Files that are missing or have drifted are flagged for sync.

The managed files manifest includes:

  • Caller workflows (enforce-repo-settings.yml, github-pages-deploy.yml, require-linked-issue.yml)
  • Issue and PR templates
  • CONTRIBUTING.md, CLAUDE.md, .editorconfig, .gitignore, LICENSE
  • .pre-commit-config.yaml

The workflow detects which package ecosystems exist in the downstream repository:

  • npmpackage.json exists
  • piprequirements.txt, pyproject.toml, or setup.py exists
  • dockerDockerfile exists

It generates a .github/dependabot.yml with a github-actions ecosystem entry (always included) plus entries for each detected ecosystem. All ecosystems use weekly Monday schedules with conventional commit prefixes and minor/patch grouping.

Each downstream repository receives a generated README.md built from two sources:

  • README.md.tpl — a template in the docs-control root with placeholders (__TITLE__, __DESCRIPTION__, __REPO_NAME__, __DOCS_URL__)
  • docs-sites.json — provides the human-readable label and description for each repository by matching the repository name against the URL field
.github/config/docs-sites.json
[
{
"label": "f5xc Docs Builder",
"url": "https://f5xc-salesdemos.github.io/docs-builder/llms-full.txt",
"description": "Containerized Astro + Starlight documentation build system"
},
{
"label": "XC Docs Theme",
"url": "https://f5xc-salesdemos.github.io/docs-theme/llms-full.txt",
"description": "Shared branding and styling for F5 Distributed Cloud documentation sites"
},
{
"label": "F5 XC Docs",
"url": "https://f5xc-salesdemos.github.io/docs/llms-full.txt",
"description": "Organization landing page for F5 Distributed Cloud documentation"
},
{
"label": "Administration",
"url": "https://f5xc-salesdemos.github.io/administration/llms-full.txt",
"description": "F5 XC administration and tenant management"
},
{
"label": "NGINX",
"url": "https://f5xc-salesdemos.github.io/nginx/llms-full.txt",
"description": "F5 XC NGINX integration and configuration"
},
{
"label": "Observability",
"url": "https://f5xc-salesdemos.github.io/observability/llms-full.txt",
"description": "F5 XC observability and monitoring"
},
{
"label": "Web App Scanning",
"url": "https://f5xc-salesdemos.github.io/was/llms-full.txt",
"description": "F5 XC web application scanning"
},
{
"label": "Multi-Cloud Networking",
"url": "https://f5xc-salesdemos.github.io/mcn/llms-full.txt",
"description": "F5 XC multi-cloud networking"
},
{
"label": "DNS",
"url": "https://f5xc-salesdemos.github.io/dns/llms-full.txt",
"description": "F5 XC DNS management"
},
{
"label": "CDN",
"url": "https://f5xc-salesdemos.github.io/cdn/llms-full.txt",
"description": "F5 XC content delivery network"
},
{
"label": "Bot Standard",
"url": "https://f5xc-salesdemos.github.io/bot-standard/llms-full.txt",
"description": "F5 XC standard bot defense"
},
{
"label": "Bot Advanced",
"url": "https://f5xc-salesdemos.github.io/bot-advanced/llms-full.txt",
"description": "F5 XC advanced bot defense"
},
{
"label": "DDoS",
"url": "https://f5xc-salesdemos.github.io/ddos/llms-full.txt",
"description": "F5 XC DDoS protection"
},
{
"label": "WAF",
"url": "https://f5xc-salesdemos.github.io/waf/llms-full.txt",
"description": "F5 XC web application firewall"
},
{
"label": "API Security",
"url": "https://f5xc-salesdemos.github.io/api-protection/llms-full.txt",
"description": "F5 XC API security"
},
{
"label": "Client-Side Defense",
"url": "https://f5xc-salesdemos.github.io/csd/llms-full.txt",
"description": "F5 XC client-side defense"
}
]

The workflow matches the repository name against docs-sites.json URLs to find the label and description. It falls back to a capitalized repository name for the title and the GitHub API repository description if no match is found.

When drift is detected in any static or dynamic file, the workflow:

  1. Creates a GitHub issue documenting the drifted files
  2. Creates a governance/sync-managed-files branch from main HEAD
  3. Commits the canonical or generated content for each drifted file
  4. Opens a PR linking to the issue with Closes #N
  5. Attempts auto-merge

If a sync PR is already open, the workflow attempts to merge it rather than creating a duplicate.

Governance sync PRs are automatically merged when CI checks pass:

  1. Polling — waits up to 180 seconds for CI checks to appear, polling every 15 seconds
  2. Watch — once checks are detected, watches them to completion
  3. Merge with retries — if CI passes, attempts a squash merge up to 3 times with exponential backoff (5s, 10s, 20s)
  4. Graceful fallback — if CI fails or the merge cannot complete after retries, the PR is left open for manual review