A simple, effective Python tool to synchronize Kubernetes release notes across YAML map files, JSON, and Markdown files.
When reviewers suggest changes to release note map files during PR review, authors must manually update:
releases/release-x.xx/release-notes/maps/pr-XXXXX-map.yaml(edited by reviewers)releases/release-x.xx/release-notes/release-notes-draft.json(needs manual sync)releases/release-x.xx/release-notes/release-notes-draft.md(needs manual sync)
This manual process is time-consuming and error-prone.
This tool automates the synchronization with two modes:
- Validate Mode: Check consistency across all files without making changes
- Sync Mode: Apply changes from map files to JSON and Markdown with interactive diffs
Note
Refer – Quickstart.md
This project uses uv for fast, reliable Python package management.
# Install uv if you haven't already
curl -LsSf https://astral.sh/uv/install.sh | sh
# Navigate to tools directory
cd releases/tools
# Install dependencies (uv will create a virtual environment automatically)
uv sync
# OR if pyproject.toml doesn't exist yet, install dependencies directly
uv pip install pyyaml colorama tabulate gitpython# Validate files changed in your recent commit
python sync_tool.py validate --since-commit HEAD~1 --release 1.35
# Sync those changes interactively
python sync_tool.py sync --since-commit HEAD~1 --release 1.35
# Validate entire release (pre-release check)
python sync_tool.py validate --global --release 1.35The tool follows a simple, functional design:
Map File (Source of Truth)
↓
JSON text field (sync from map)
↓
JSON markdown field (update text portion, preserve metadata)
↓
Markdown file (render from JSON markdown)
- Map files are always the source of truth
- Simple Python - No OOP, no heavy frameworks, just functions
- User-friendly - Clear diffs, interactive prompts, colored output
- Safe by default - Validate before sync, confirm each change
- ARCHITECTURE.md - Complete system design, data flow, and component specifications
- IMPLEMENTATION_GUIDE.md - Detailed algorithms, pseudocode, flowcharts, and edge cases
- README.md - This file - quick start and overview
Check consistency without making changes.
# Validate changes since a commit
uv run python sync_tool.py validate --since-commit <commit-hash> --release 1.35
# Validate specific PRs
uv run python sync_tool.py validate --prs 133540,132549 --release 1.35
# Validate entire release
uv run python sync_tool.py validate --global --release 1.35
# Output formats
uv run python sync_tool.py validate --global --release 1.35 --output table # default
uv run python sync_tool.py validate --global --release 1.35 --output json
uv run python sync_tool.py validate --global --release 1.35 --output csvOutput Example:
Validation Results:
===================
✓ CORRECT (45 entries)
✗ INCORRECT (2 entries)
PR #133540:
- JSON text: MISMATCH
- JSON markdown: MISMATCH
- MD content: MISMATCH
⚠ MISSING (1 entry)
PR #999999: Exists in maps but not in JSON
Apply changes from map files to JSON and Markdown.
# Sync changes since a commit (interactive)
uv run python sync_tool.py sync --since-commit <commit-hash> --release 1.35
# Sync specific PRs
uv run python sync_tool.py sync --prs 133540,132549 --release 1.35
# Dry run (see what would change)
uv run python sync_tool.py sync --since-commit HEAD~1 --release 1.35 --dry-run
# Auto-approve all changes (dangerous!)
uv run python sync_tool.py sync --since-commit HEAD~1 --release 1.35 --auto-yesInteractive Flow:
Syncing PR #133540
===================
[DIFF 1/3] JSON text field:
--- OLD
+++ NEW
@@ -1 +1 @@
-Added validation to ensure log-flush-frequency is a positive value.
+Added validation to ensure `log-flush-frequency` is a positive value, returning an error instead of causing a panic.
[DIFF 2/3] JSON markdown field:
[... similar diff ...]
[DIFF 3/3] Markdown file:
[... similar diff ...]
Apply changes for PR #133540? [y/n/q]: y
✓ Changes applied successfully!
Syncing PR #132549
===================
[... next PR ...]
You've updated map files based on reviewer feedback:
# 1. Check what changed
git diff HEAD~1 releases/release-1.35/release-notes/maps/
# 2. Validate those changes
uv run python sync_tool.py validate --since-commit HEAD~1 --release 1.35
# 3. Sync the changes
uv run python sync_tool.py sync --since-commit HEAD~1 --release 1.35
# 4. Review and commit
git diff
git add releases/release-1.35/release-notes/
git commit -m "sync: Update release notes for PRs 133540, 132549"Before cutting a release, validate everything:
# Check entire release for consistency
uv run python sync_tool.py validate --global --release 1.35
# If issues found, review them
uv run python sync_tool.py validate --global --release 1.35 --output json > validation.json
# Fix issues and sync
uv run python sync_tool.py sync --global --release 1.35Fix one specific PR's release notes:
# 1. Edit the map file
vim releases/release-1.35/release-notes/maps/pr-133540-map.yaml
# 2. Validate just that PR
uv run python sync_tool.py validate --prs 133540 --release 1.35
# 3. Sync just that PR
uv run python sync_tool.py sync --prs 133540 --release 1.35-
Map → JSON text field: Direct copy with normalization
- Multi-line YAML collapsed to single line (unless explicit
\n) - Whitespace normalized
- Multi-line YAML collapsed to single line (unless explicit
-
JSON text → JSON markdown field: Update text portion only
- Extract text before
([#PR...pattern - Replace with new text
- Preserve PR link, author, and SIG metadata
- Extract text before
-
JSON markdown → Markdown file: Direct replacement
- Find old markdown line in file
- Replace with new markdown line
In map file (YAML):
text: Line one
and line twoBecomes: "Line one and line two"
With explicit newlines:
text: Line one\nLine twoStays: "Line one\nLine two" (rendered as line break in markdown)
- Validation before sync: Run validate first to see what needs fixing
- Interactive approval: Confirm each change individually
- Dry-run mode: See what would change without applying
- Clear diffs: See exact old→new changes before approving
- Git awareness: Optionally detect uncommitted changes
- Backup option: Save JSON/MD before modifications
The tool handles common issues gracefully:
- Missing map file: Reports in validation, skips in sync
- Missing JSON entry: Error - cannot sync without base entry
- Corrupted YAML: Skips with clear error message
- File permission errors: Aborts with helpful message
- User cancellation: Clean exit, no partial changes