8. Synchronizer
Sync CLI 🔁
The Sync CLI manages framework versions, migrations, and releases across all repositories in the dynatrace-wwse organization. One tool to keep every repo up to date.
Overview#
The Sync CLI runs from the codespaces-framework directory and operates on repos listed in repos.yaml. It follows a local-first workflow: repos are cloned locally, changes are made on branches, then pushed as PRs.
cd codespaces-framework
PYTHONPATH=. python3 -m sync.cli <command> [options]
Full Release Cycle#
The workflow for updating all repos to a new framework version:
graph LR
A[Release] --> B[Push Update]
B --> C[Monitor PRs]
C --> D[Merge]
D --> E[Tag + Release]
E --> F[Cleanup]
Step 1: Release a new framework version#
Make your changes to the framework, commit them, then release:
# Bump patch (1.2.5 → 1.2.6), tag, push, create GitHub Release
sync release --part patch
This creates a git tag on codespaces-framework, updates the default version in cli.py, and creates a GitHub Release with a categorized changelog (features, fixes, docs, maintenance).
To create a release for an existing tag without bumping:
sync release
Step 2: Push updates to all repos#
# Preview what would change
sync push-update --framework-version 1.2.6 --dry-run
# Execute: pull main → branch → full migrate → commit → push → PR
sync push-update --framework-version 1.2.6
Per repo, push-update:
- 📥 Clones if not present locally
- 🔄 Checks out main and pulls latest
- 🌿 Creates branch
sync/framework-1.2.6 - 🔧 Runs full migration (Category A cleanup, templates, mkdocs, .env, README badges, devcontainer.json fixes)
- 📝 Commits all changes
- 🚀 Pushes branch and creates PR
On failure at any step, the branch is left in place for manual intervention.
To re-push changes at the same version (e.g. after fixing badges or templates):
sync push-update --framework-version 1.2.6 --force
Step 3: Monitor CI and merge#
# List all open PRs with CI status
sync list-pr
# Filter to sync PRs for a specific version
sync list-pr --framework-version 1.2.6
# Merge passing PRs
sync list-pr --merge
# Close old PRs that are superseded
sync list-pr --framework-version 1.2.5 --close -c "Superseded by 1.2.6"
Step 4: Tag consumer repos and create releases#
After all PRs are merged:
# Preview
sync tag --framework-version 1.2.6 --bump patch --release --dry-run
# Create combined version tags + GitHub Releases
sync tag --framework-version 1.2.6 --bump patch --release
Each repo gets a tag like v1.2.6_1.0.1 (framework version + repo version) and a GitHub Release with categorized changelog.
Step 5: Cleanup#
# Delete merged branches (local + remote)
sync cleanup-branches
# Verify everything is clean
sync validate
Migration: What Happens#
When push-update or migrate runs on a repo, it executes these phases:
| Phase | Action |
|---|---|
| 1. Audit | Identifies Category A files and validates devcontainer.json |
| 1b. Fix devcontainer.json | Auto-bumps image v1.0/v1.1 → v1.2 |
| 2. Clean Category A | Removes framework-owned files (now pulled from cache) |
| 3. Thin Makefile | Installs wrapper that delegates to cached makefile.sh |
| 4. source_framework.sh | Installs/updates versioned pull mechanism |
| 5. mkdocs.yaml | Converts to INHERIT: mkdocs-base.yaml pattern |
| 6. overrides/main.html | Parameterizes RUM snippet, extracts URL to mkdocs.yaml |
| 7. deploy-ghpages.yaml | CI fetches mkdocs-base.yaml at framework version |
| 8. .gitignore | Adds cache, mkdocs-base, Dockerfile.framework entries |
| 9. .env location | Moves from runlocal/.env to .devcontainer/.env |
| 10. README badges | Updates branding, adds missing badges, fixes integration test link |
All Commands#
Migration & Updates#
| Command | Description | Example |
|---|---|---|
push-update |
Full workflow: pull → branch → migrate → push → PR | sync push-update --framework-version 1.2.6 |
migrate |
Local migration preview (no git operations) | sync migrate --dry-run |
revert |
Undo uncommitted changes | sync revert --repo template |
validate |
Check schema, GitHub, templates, badges | sync validate |
Versioning & Releases#
| Command | Description | Example |
|---|---|---|
release |
Tag framework, create GitHub Release | sync release --part patch |
tag |
Tag consumer repos with combined version | sync tag --framework-version 1.2.6 --bump patch --release |
Repository Management#
| Command | Description | Example |
|---|---|---|
clone |
Clone repos from repos.yaml | sync clone --all |
protect-main |
Apply branch protection rules | sync protect-main |
cleanup-branches |
Delete merged branches | sync cleanup-branches --dry-run |
Monitoring#
| Command | Description | Example |
|---|---|---|
list-pr |
List PRs, approve, merge, or close | sync list-pr --merge |
list-issues |
List open issues | sync list-issues --label bug |
status |
Show version drift | sync status |
list |
List registered repos | sync list --sync-managed --json |
Common Recipes#
First-time setup#
sync clone # Clone all repos locally
sync validate # Check current state
sync migrate --dry-run # Preview migration
Deploy a framework update#
sync release --part patch # 1.2.5 → 1.2.6
sync push-update --framework-version 1.2.6 # Create PRs
sync list-pr --framework-version 1.2.6 # Monitor CI
sync list-pr --merge # Merge passing
sync tag --framework-version 1.2.6 --bump patch --release # Tag + release
sync cleanup-branches # Clean up
Fix something and re-push at the same version#
# Edit the framework, commit
sync push-update --framework-version 1.2.6 --force
Close old PRs#
sync list-pr --framework-version 1.2.5 --close -c "Superseded by 1.2.6"
Housekeeping#
sync protect-main # Protect main on all repos
sync cleanup-branches # Delete stale branches
sync list-issues # Check for open issues
Key Files#
| File | Purpose |
|---|---|
sync/cli.py |
CLI entry point |
sync/core/repos.py |
repos.yaml parsing, RepoEntry dataclass |
sync/core/version.py |
Version parsing and bumping |
sync/core/github_api.py |
GitHub API via gh CLI |
sync/core/local_git.py |
Local git operations |
sync/commands/migrate.py |
Migration logic, file classification, templates |
sync/commands/push_update.py |
Local-first push-update |
sync/commands/release.py |
Framework release with changelog |
sync/commands/tag.py |
Consumer repo tagging + releases |
sync/commands/list_pr.py |
PR listing, approve, merge, close |
repos.yaml |
Registry of all repos |
Command Scope#
| Command | Repos it operates on |
|---|---|
push-update, migrate, revert, tag |
sync-managed only (consumer repos) |
list-pr, list-issues, protect-main, cleanup-branches |
all active repos (including framework, website, tracker) |
clone |
sync-managed by default, --all for everything |
release |
framework repo only |