From dacda7721c366bd5593ff6ff8a9a7cef84a9bd37 Mon Sep 17 00:00:00 2001 From: maliming Date: Tue, 10 Mar 2026 15:14:20 +0800 Subject: [PATCH 1/2] fix: preserve doc preamble and normalize preview version in update_dependency_changes script - Add extract_preamble() to retain SEO metadata before the heading when rewriting the doc - Add normalize_version() to map -preview suffix to -rc.1 (preview == RC1 in ABP versioning) - Add unit tests (Test 17-19) covering preview, rc.N, and stable version normalization --- .../scripts/test_update_dependency_changes.py | 44 +++++++++++++++++-- .github/scripts/update_dependency_changes.py | 21 ++++++++- 2 files changed, 60 insertions(+), 5 deletions(-) diff --git a/.github/scripts/test_update_dependency_changes.py b/.github/scripts/test_update_dependency_changes.py index f8cf0100f3..b5ca1603d8 100644 --- a/.github/scripts/test_update_dependency_changes.py +++ b/.github/scripts/test_update_dependency_changes.py @@ -14,7 +14,7 @@ import sys import os sys.path.insert(0, os.path.dirname(__file__)) -from update_dependency_changes import merge_changes, render_section +from update_dependency_changes import merge_changes, render_section, normalize_version def test_update_then_revert(): @@ -367,12 +367,44 @@ def test_document_format(): print("-" * 60 + "\n") +def test_normalize_version_preview(): + """Test: preview suffix is normalized to rc.1.""" + print("Test 17: normalize_version - preview -> rc.1") + assert normalize_version("10.1.0-preview") == "10.1.0-rc.1", \ + f"Expected '10.1.0-rc.1', got: {normalize_version('10.1.0-preview')}" + assert normalize_version("10.2.0-preview") == "10.2.0-rc.1", \ + f"Expected '10.2.0-rc.1', got: {normalize_version('10.2.0-preview')}" + print("✓ Passed: preview correctly normalized to rc.1\n") + + +def test_normalize_version_rc(): + """Test: rc.N versions are unchanged.""" + print("Test 18: normalize_version - rc.N unchanged") + assert normalize_version("10.1.0-rc.1") == "10.1.0-rc.1", \ + f"Expected '10.1.0-rc.1', got: {normalize_version('10.1.0-rc.1')}" + assert normalize_version("10.2.0-rc.1") == "10.2.0-rc.1", \ + f"Expected '10.2.0-rc.1', got: {normalize_version('10.2.0-rc.1')}" + assert normalize_version("10.2.0-rc.2") == "10.2.0-rc.2", \ + f"Expected '10.2.0-rc.2', got: {normalize_version('10.2.0-rc.2')}" + print("✓ Passed: rc.N versions unchanged\n") + + +def test_normalize_version_stable(): + """Test: stable versions are unchanged.""" + print("Test 19: normalize_version - stable unchanged") + assert normalize_version("10.1.0") == "10.1.0", \ + f"Expected '10.1.0', got: {normalize_version('10.1.0')}" + assert normalize_version("10.2.0") == "10.2.0", \ + f"Expected '10.2.0', got: {normalize_version('10.2.0')}" + print("✓ Passed: stable versions unchanged\n") + + def run_all_tests(): """Run all test cases.""" print("=" * 70) print("Testing update_dependency_changes.py") print("=" * 70 + "\n") - + test_update_then_revert() test_add_then_remove_same_version() test_remove_then_add_same_version() @@ -389,9 +421,12 @@ def run_all_tests(): test_add_add() test_complex_chain_ending_in_original() test_document_format() - + test_normalize_version_preview() + test_normalize_version_rc() + test_normalize_version_stable() + print("=" * 70) - print("All 16 tests passed! ✓") + print("All 19 tests passed! ✓") print("=" * 70) print("\nTest coverage summary:") print(" ✓ Basic scenarios (update, add, remove)") @@ -399,6 +434,7 @@ def run_all_tests(): print(" ✓ Complex multi-step sequences") print(" ✓ Edge cases and duplicates") print(" ✓ Document format validation") + print(" ✓ Version normalization (preview -> rc.1)") print("=" * 70) diff --git a/.github/scripts/update_dependency_changes.py b/.github/scripts/update_dependency_changes.py index 05e0019470..f4f2c3db6c 100644 --- a/.github/scripts/update_dependency_changes.py +++ b/.github/scripts/update_dependency_changes.py @@ -9,6 +9,22 @@ HEADER = "# Package Version Changes\n" DOC_PATH = os.environ.get("DOC_PATH", "docs/en/package-version-changes.md") +def extract_preamble(content): + """Extract content before the '# Package Version Changes' heading.""" + header_pattern = re.compile(r"^# Package Version Changes\s*$", re.MULTILINE) + match = header_pattern.search(content) + if match: + return content[: match.start()] + return "" + + +def normalize_version(version): + """Normalize version string: replace -preview suffix with -rc.1.""" + if version and version.endswith("-preview"): + return version[: -len("-preview")] + "-rc.1" + return version + + def get_version(): """Read the current version from common.props.""" try: @@ -275,7 +291,7 @@ def main(): pr_number = f"#{pr_arg}" - version = get_version() + version = normalize_version(get_version()) if not version: print("Could not read version from common.props.") sys.exit(1) @@ -297,6 +313,7 @@ def main(): # Load existing document from the base branch existing_content = get_existing_doc_from_base(base_ref) + preamble = extract_preamble(existing_content) if existing_content else "" sections = parse_document(existing_content) if existing_content else [] # Find existing section for this version @@ -320,6 +337,8 @@ def main(): if doc_dir: os.makedirs(doc_dir, exist_ok=True) with open(DOC_PATH, "w") as f: + if preamble: + f.write(preamble) f.write(HEADER + "\n") for _, text in sections: f.write(text.rstrip("\n") + "\n\n") From fb23d80440e1e6cc40613d2fd40bbbb04a93a523 Mon Sep 17 00:00:00 2001 From: maliming Date: Tue, 10 Mar 2026 15:21:28 +0800 Subject: [PATCH 2/2] test: add coverage for extract_preamble in update_dependency_changes tests --- .../scripts/test_update_dependency_changes.py | 53 +++++++++++++++++-- 1 file changed, 48 insertions(+), 5 deletions(-) diff --git a/.github/scripts/test_update_dependency_changes.py b/.github/scripts/test_update_dependency_changes.py index b5ca1603d8..fde9720590 100644 --- a/.github/scripts/test_update_dependency_changes.py +++ b/.github/scripts/test_update_dependency_changes.py @@ -14,7 +14,7 @@ import sys import os sys.path.insert(0, os.path.dirname(__file__)) -from update_dependency_changes import merge_changes, render_section, normalize_version +from update_dependency_changes import merge_changes, render_section, normalize_version, extract_preamble def test_update_then_revert(): @@ -367,9 +367,48 @@ def test_document_format(): print("-" * 60 + "\n") +def test_extract_preamble_with_seo_block(): + """Test: content with a JSON SEO block before the heading.""" + print("Test 17: extract_preamble - preamble before heading") + content = ( + "```json\n" + "//[doc-seo]\n" + "{\n" + ' "Description": "Some description."\n' + "}\n" + "```\n" + "\n" + "# Package Version Changes\n" + "\n" + "## 10.1.0-rc.1\n" + ) + result = extract_preamble(content) + assert result == "```json\n//[doc-seo]\n{\n \"Description\": \"Some description.\"\n}\n```\n\n", \ + f"Unexpected preamble: {repr(result)}" + print("✓ Passed: preamble correctly extracted\n") + + +def test_extract_preamble_no_preamble(): + """Test: heading at the very start — preamble should be empty string.""" + print("Test 18: extract_preamble - no preamble before heading") + content = "# Package Version Changes\n\n## 10.1.0-rc.1\n" + result = extract_preamble(content) + assert result == "", f"Expected empty string, got: {repr(result)}" + print("✓ Passed: empty preamble returned when heading is at start\n") + + +def test_extract_preamble_no_heading(): + """Test: no matching heading — returns empty string.""" + print("Test 19: extract_preamble - no matching heading") + content = "Some random content without the expected heading.\n" + result = extract_preamble(content) + assert result == "", f"Expected empty string, got: {repr(result)}" + print("✓ Passed: empty string returned when heading is absent\n") + + def test_normalize_version_preview(): """Test: preview suffix is normalized to rc.1.""" - print("Test 17: normalize_version - preview -> rc.1") + print("Test 20: normalize_version - preview -> rc.1") assert normalize_version("10.1.0-preview") == "10.1.0-rc.1", \ f"Expected '10.1.0-rc.1', got: {normalize_version('10.1.0-preview')}" assert normalize_version("10.2.0-preview") == "10.2.0-rc.1", \ @@ -379,7 +418,7 @@ def test_normalize_version_preview(): def test_normalize_version_rc(): """Test: rc.N versions are unchanged.""" - print("Test 18: normalize_version - rc.N unchanged") + print("Test 21: normalize_version - rc.N unchanged") assert normalize_version("10.1.0-rc.1") == "10.1.0-rc.1", \ f"Expected '10.1.0-rc.1', got: {normalize_version('10.1.0-rc.1')}" assert normalize_version("10.2.0-rc.1") == "10.2.0-rc.1", \ @@ -391,7 +430,7 @@ def test_normalize_version_rc(): def test_normalize_version_stable(): """Test: stable versions are unchanged.""" - print("Test 19: normalize_version - stable unchanged") + print("Test 22: normalize_version - stable unchanged") assert normalize_version("10.1.0") == "10.1.0", \ f"Expected '10.1.0', got: {normalize_version('10.1.0')}" assert normalize_version("10.2.0") == "10.2.0", \ @@ -421,12 +460,15 @@ def run_all_tests(): test_add_add() test_complex_chain_ending_in_original() test_document_format() + test_extract_preamble_with_seo_block() + test_extract_preamble_no_preamble() + test_extract_preamble_no_heading() test_normalize_version_preview() test_normalize_version_rc() test_normalize_version_stable() print("=" * 70) - print("All 19 tests passed! ✓") + print("All 22 tests passed! ✓") print("=" * 70) print("\nTest coverage summary:") print(" ✓ Basic scenarios (update, add, remove)") @@ -434,6 +476,7 @@ def run_all_tests(): print(" ✓ Complex multi-step sequences") print(" ✓ Edge cases and duplicates") print(" ✓ Document format validation") + print(" ✓ Preamble extraction (SEO block, no preamble, no heading)") print(" ✓ Version normalization (preview -> rc.1)") print("=" * 70)