|
29 | 29 | REVIEW_PYPROJECT = REPO_ROOT / "packages" / "pythinker-review" / "pyproject.toml" |
30 | 30 | SDK_PYPROJECT = REPO_ROOT / "sdks" / "pythinker-sdk" / "pyproject.toml" |
31 | 31 |
|
32 | | -# Single source for the three hand-authored changelog files. validate() asserts |
33 | | -# the `## Unreleased` anchor in ALL of them before any write, and rewrite() |
34 | | -# promotes the SAME list — defined once so the two can never drift (atomic |
35 | | -# Phase-2 guarantee: no partial-write if a docs file is missing its anchor). |
| 32 | +# Hand-authored changelog files. The docs changelog is intentionally excluded: |
| 33 | +# docs/en/release-notes/changelog.md is auto-synced from the root CHANGELOG.md |
| 34 | +# by docs/scripts/sync-changelog.mjs and must not be edited directly. |
36 | 35 | CHANGELOG_FILES = ( |
37 | 36 | REPO_ROOT / "CHANGELOG.md", |
38 | | - REPO_ROOT / "docs" / "en" / "release-notes" / "changelog.md", |
39 | 37 | REPO_ROOT / "docs" / "en" / "release-notes" / "breaking-changes.md", |
40 | 38 | ) |
| 39 | +DOCS_CHANGELOG_SCRIPT = REPO_ROOT / "docs" / "scripts" / "sync-changelog.mjs" |
41 | 40 |
|
42 | 41 | SEMVER_RE = re.compile(r"^(\d+)\.(\d+)\.(\d+)$") |
43 | 42 | _DEP_PIN_RE = re.compile( |
@@ -157,6 +156,10 @@ def rewrite_version_in_files(paths: list[Path], *, old: str, new: str) -> None: |
157 | 156 | path.write_text(rewrite_version_strings(original, old=old, new=new), encoding="utf-8") |
158 | 157 |
|
159 | 158 |
|
| 159 | +def sync_docs_changelog() -> None: |
| 160 | + subprocess.run(["node", str(DOCS_CHANGELOG_SCRIPT)], cwd=REPO_ROOT / "docs", check=True) |
| 161 | + |
| 162 | + |
160 | 163 | def _run(cmd: list[str], *, dry_run: bool, check: bool = True) -> subprocess.CompletedProcess[str]: |
161 | 164 | if dry_run: |
162 | 165 | print(f"[dry-run] {' '.join(cmd)}") |
@@ -185,8 +188,9 @@ def validate(target: str) -> None: |
185 | 188 | if head != remote: |
186 | 189 | raise ReleaseError("current HEAD is not origin/main; switch to main before release prep") |
187 | 190 | assert_monotonic(current=read_project_version(ROOT_PYPROJECT), target=target) |
188 | | - # Assert the `## Unreleased` anchor in ALL changelog files BEFORE any write |
189 | | - # (same list rewrite() promotes) so Phase 2 cannot partially rewrite the tree. |
| 191 | + # Assert the `## Unreleased` anchor in ALL hand-authored changelog files BEFORE |
| 192 | + # any write (same list rewrite() promotes) so Phase 2 cannot partially rewrite |
| 193 | + # the tree. |
190 | 194 | for changelog in CHANGELOG_FILES: |
191 | 195 | if _UNRELEASED_RE.search(changelog.read_text(encoding="utf-8")) is None: |
192 | 196 | raise ReleaseError(f"{changelog} has no `## Unreleased` section") |
@@ -214,6 +218,7 @@ def rewrite(target: str, *, bump_core: str | None, bump_host: str | None) -> Non |
214 | 218 | today = date.today().isoformat() |
215 | 219 | for changelog in CHANGELOG_FILES: |
216 | 220 | promote_changelog(changelog, target, release_date=today) |
| 221 | + sync_docs_changelog() |
217 | 222 | rewrite_version_in_files( |
218 | 223 | [ |
219 | 224 | REPO_ROOT / "README.md", |
|
0 commit comments