diff --git a/scripts/sync_release_history.py b/scripts/sync_release_history.py index 88b345c..5072ea1 100755 --- a/scripts/sync_release_history.py +++ b/scripts/sync_release_history.py @@ -13,6 +13,11 @@ HEADING_RE = re.compile(r"^(#{2,3})\s+(.+?)\s*$") LINK_RE = re.compile(r"\[([^\]]+)\]\((https?://[^)]+)\)") CODE_RE = re.compile(r"`([^`]+)`") +RST_HEADER = [ + ".. SPDX-FileCopyrightText: 2026 LibreCode coop and contributors", + ".. SPDX-License-" + "Identifier: AGPL-3.0-or-later", + "", +] def load_json(path: Path) -> dict[str, object]: @@ -33,7 +38,7 @@ def markdown_section_to_rst(section: str, version: str) -> str: if not lines: raise ValueError("changelog section must not be empty") - output: list[str] = [] + output: list[str] = [*RST_HEADER, ".. This file is generated from LibreSign/libresign release history.", ""] first_heading_seen = False for raw in lines: match = HEADING_RE.match(raw) @@ -85,6 +90,7 @@ def render_major_index(major: int, versions: list[str]) -> str: ordered = sorted(versions, key=version_key, reverse=True) title = f"LibreSign {major}" body = [ + *RST_HEADER, ".. This file is generated from LibreSign release history. Do not edit release text here manually.", "", title, @@ -101,6 +107,7 @@ def render_major_index(major: int, versions: list[str]) -> str: def render_root_index(majors: list[int]) -> str: title = "Release history" body = [ + *RST_HEADER, ".. This file is generated. Release text is sourced from LibreSign/libresign per-major changelogs.", "", title, diff --git a/tests/test_sync_release_history.py b/tests/test_sync_release_history.py index 9590a0c..6a384bf 100644 --- a/tests/test_sync_release_history.py +++ b/tests/test_sync_release_history.py @@ -25,6 +25,7 @@ def test_markdown_release_section_becomes_browsable_rst(self) -> None: self.assertIn("15.1.0 - 2026-09-21", rendered) self.assertIn("Added\n-----", rendered) self.assertIn("`#10 `_", rendered) + self.assertIn("AGPL-3.0-or-later", rendered) def test_synchronization_requires_successful_matching_publication(self) -> None: with tempfile.TemporaryDirectory() as directory: @@ -67,6 +68,7 @@ def test_synchronization_is_idempotent_and_indexes_major(self) -> None: self.assertEqual(first, second) self.assertIn("15.1.0", (docs / "developer_manual/release-history/15/index.rst").read_text(encoding="utf-8")) self.assertIn("LibreSign 15 <15/index>", (docs / "developer_manual/release-history/index.rst").read_text(encoding="utf-8")) + self.assertIn("AGPL-3.0-or-later", (docs / "developer_manual/release-history/15/index.rst").read_text(encoding="utf-8")) def test_versions_sort_semantically(self) -> None: versions = ["15.9.0", "15.10.0", "15.10.0-rc.1", "15.2.4"]