Problem: website/docs/releases.md and the README's "Recent Updates"
block had drifted badly. README claimed v9.6.3 was the latest; the
actual latest is v9.7.0 (and there are 60 releases on record going
back to v4.0.0).
Solution:
- tools/sync_release_notes.py: pulls every non-draft release from the
GitHub Releases API and renders both files. Uses `gh api` when
available (handles auth + TLS cleanly), falls back to urllib +
certifi when not. Supports --check for CI drift detection.
- README.md: gets a sentinel-bracketed `<!-- recent-updates:start -->
... <!-- recent-updates:end -->` block the script regenerates
surgically — never touches the surrounding content. Latest 5
releases with tag, date, link.
- website/docs/releases.md: full 60-release history, grouped by minor
version, each release body inside a collapsible `<details>` block.
Now shows the real v9.7.0 → v4.0.0 span.
- .github/workflows/sync-releases.yml: triggers the sync on every
release event (published/edited/unpublished/deleted), daily at
11:00 UTC (catches out-of-band edits), and on workflow_dispatch.
Commits directly to beta with [skip ci]. PRs run --check only.
- /contributing/docs page: new "Release notes sync" section
documenting the do-not-edit contract for releases.md and the
recent-updates block, plus the manual sync commands.
Verified: sync ran end-to-end via `gh api`, renders 60 releases into
1304 lines of releases.md + 5 entries in the README block. npm run
build passes.