From ce1d0cc9cb5c728a94c402d4a26935c6736cee75 Mon Sep 17 00:00:00 2001 From: ohmayr Date: Tue, 21 Oct 2025 22:18:56 +0000 Subject: [PATCH 1/4] chore: update docs changelog in release init --- .generator/cli.py | 7 ++++++- .generator/test_cli.py | 44 +++++++++++++++++++++++++----------------- 2 files changed, 32 insertions(+), 19 deletions(-) diff --git a/.generator/cli.py b/.generator/cli.py index ef68e6d7b86e..fc4c035e678a 100644 --- a/.generator/cli.py +++ b/.generator/cli.py @@ -1373,6 +1373,12 @@ def _update_changelog_for_library( ) _write_text_file(changelog_dest, updated_content) + docs_relative_path = f"packages/{library_id}/docs/CHANGELOG.md" + docs_changelog_src = f"{repo}/{docs_relative_path}" + if os.path.lexists(docs_changelog_src): + docs_changelog_dst = f"{output}/{docs_relative_path}" + _write_text_file(docs_changelog_dst, updated_content) + def _is_mono_repo(repo: str) -> bool: """Determines if a library is generated or handwritten. @@ -1424,7 +1430,6 @@ def handle_release_init( ) if is_mono_repo: - # only a mono repo has a global changelog _update_global_changelog( f"{repo}/CHANGELOG.md", diff --git a/.generator/test_cli.py b/.generator/test_cli.py index 67be0b13d1f4..3dcb5b5c4cab 100644 --- a/.generator/test_cli.py +++ b/.generator/test_cli.py @@ -312,6 +312,7 @@ def test_handle_configure_no_new_library(mocker): with pytest.raises(ValueError, match="Configuring a new library failed."): handle_configure() + def test_create_new_changelog_for_library(mocker): """Tests that the changelog files are created correctly.""" library_id = "google-cloud-language" @@ -325,7 +326,9 @@ def test_create_new_changelog_for_library(mocker): docs_changelog_path = f"{output}/packages/{library_id}/docs/CHANGELOG.md" # Check that makedirs was called for both parent directories - mock_makedirs.assert_any_call(os.path.dirname(package_changelog_path), exist_ok=True) + mock_makedirs.assert_any_call( + os.path.dirname(package_changelog_path), exist_ok=True + ) mock_makedirs.assert_any_call(os.path.dirname(docs_changelog_path), exist_ok=True) assert mock_makedirs.call_count == 2 @@ -1141,29 +1144,34 @@ def test_get_previous_version_failure(mock_state_file): _get_previous_version("google-cloud-does-not-exist", LIBRARIAN_DIR) -def test_update_changelog_for_library_success(mocker): - m = mock_open() - +def test_update_changelog_for_library_writes_both_changelogs(mocker): + """Tests that _update_changelog_for_library writes to both changelogs.""" mock_content = """# Changelog [PyPI History][1] [1]: https://pypi.org/project/google-cloud-language/#history - -## [2.17.2](https://github.com/googleapis/google-cloud-python/compare/google-cloud-language-v2.17.1...google-cloud-language-v2.17.2) (2025-06-11) - """ - with unittest.mock.patch("cli.open", m): - mocker.patch("cli._read_text_file", return_value=mock_content) - _update_changelog_for_library( - "repo", - "output", - _MOCK_LIBRARY_CHANGES, - "1.2.3", - "1.2.2", - "google-cloud-language", - "CHANGELOG.md", - ) + mock_read = mocker.patch("cli._read_text_file", return_value=mock_content) + mock_write = mocker.patch("cli._write_text_file") + mock_path_exists = mocker.patch("cli.os.path.lexists", return_value=True) + _update_changelog_for_library( + "repo", + "output", + _MOCK_LIBRARY_CHANGES, + "1.2.3", + "1.2.2", + "google-cloud-language", + "packages/google-cloud-language/CHANGELOG.md", + ) + + assert mock_write.call_count == 2 + mock_write.assert_any_call( + "output/packages/google-cloud-language/CHANGELOG.md", mocker.ANY + ) + mock_write.assert_any_call( + "output/packages/google-cloud-language/docs/CHANGELOG.md", mocker.ANY + ) def test_process_changelog_success(): From b9eef68fcd58427e368bef689a9cab9b5320074e Mon Sep 17 00:00:00 2001 From: ohmayr Date: Tue, 21 Oct 2025 23:07:56 +0000 Subject: [PATCH 2/4] add docstring --- .generator/cli.py | 1 + 1 file changed, 1 insertion(+) diff --git a/.generator/cli.py b/.generator/cli.py index fc4c035e678a..4a800e66c284 100644 --- a/.generator/cli.py +++ b/.generator/cli.py @@ -1361,6 +1361,7 @@ def _update_changelog_for_library( previous_version(str): The version in state.yaml for a given library library_id(str): The id of the library where the changelog should be updated. + relative_path(str): The path to the changelog file relative to the repository root. """ changelog_src = f"{repo}/{relative_path}" changelog_dest = f"{output}/{relative_path}" From 43f8f5b2421635fefdf004c9672341495c3b134b Mon Sep 17 00:00:00 2001 From: ohmayr Date: Tue, 21 Oct 2025 23:15:04 +0000 Subject: [PATCH 3/4] fix for handwritten clients --- .generator/cli.py | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/.generator/cli.py b/.generator/cli.py index 4a800e66c284..b38d5e2e233c 100644 --- a/.generator/cli.py +++ b/.generator/cli.py @@ -1345,7 +1345,7 @@ def _update_changelog_for_library( version: str, previous_version: str, library_id: str, - relative_path: str, + is_mono_repo: bool, ): """Prepends a new release entry with multiple, grouped changes, to a changelog. @@ -1361,8 +1361,15 @@ def _update_changelog_for_library( previous_version(str): The version in state.yaml for a given library library_id(str): The id of the library where the changelog should be updated. - relative_path(str): The path to the changelog file relative to the repository root. + is_mono_repo(bool): True if the current repository is a mono-repo. """ + if is_mono_repo: + relative_path = f"packages/{library_id}/CHANGELOG.md" + docs_relative_path = f"packages/{library_id}/docs/CHANGELOG.md" + else: + relative_path = "CHANGELOG.md" + docs_relative_path = f"docs/CHANGELOG.md" + changelog_src = f"{repo}/{relative_path}" changelog_dest = f"{output}/{relative_path}" updated_content = _process_changelog( @@ -1374,7 +1381,6 @@ def _update_changelog_for_library( ) _write_text_file(changelog_dest, updated_content) - docs_relative_path = f"packages/{library_id}/docs/CHANGELOG.md" docs_changelog_src = f"{repo}/{docs_relative_path}" if os.path.lexists(docs_changelog_src): docs_changelog_dst = f"{output}/{docs_relative_path}" @@ -1455,10 +1461,8 @@ def handle_release_init( if is_mono_repo: path_to_library = f"packages/{library_id}" - changelog_relative_path = f"packages/{library_id}/CHANGELOG.md" else: path_to_library = "." - changelog_relative_path = "CHANGELOG.md" _update_version_for_library(repo, output, path_to_library, version) _update_changelog_for_library( @@ -1468,7 +1472,7 @@ def handle_release_init( version, previous_version, library_id, - relative_path=changelog_relative_path, + is_mono_repo=is_mono_repo, ) except Exception as e: From 45e91130a1d67fa8a751b645971ec49c9e0b9b26 Mon Sep 17 00:00:00 2001 From: ohmayr Date: Tue, 21 Oct 2025 23:21:15 +0000 Subject: [PATCH 4/4] add coverage --- .generator/test_cli.py | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/.generator/test_cli.py b/.generator/test_cli.py index 3dcb5b5c4cab..7b0b17ac069f 100644 --- a/.generator/test_cli.py +++ b/.generator/test_cli.py @@ -1162,7 +1162,7 @@ def test_update_changelog_for_library_writes_both_changelogs(mocker): "1.2.3", "1.2.2", "google-cloud-language", - "packages/google-cloud-language/CHANGELOG.md", + is_mono_repo=True, ) assert mock_write.call_count == 2 @@ -1174,6 +1174,32 @@ def test_update_changelog_for_library_writes_both_changelogs(mocker): ) +def test_update_changelog_for_library_single_repo(mocker): + """Tests that _update_changelog_for_library writes to both changelogs in a single repo.""" + mock_content = """# Changelog + +[PyPI History][1] + +[1]: https://pypi.org/project/google-cloud-language/#history +""" + mock_read = mocker.patch("cli._read_text_file", return_value=mock_content) + mock_write = mocker.patch("cli._write_text_file") + mock_path_exists = mocker.patch("cli.os.path.lexists", return_value=True) + _update_changelog_for_library( + "repo", + "output", + _MOCK_LIBRARY_CHANGES, + "1.2.3", + "1.2.2", + "google-cloud-language", + is_mono_repo=False, + ) + + assert mock_write.call_count == 2 + mock_write.assert_any_call("output/CHANGELOG.md", mocker.ANY) + mock_write.assert_any_call("output/docs/CHANGELOG.md", mocker.ANY) + + def test_process_changelog_success(): """Tests that value error is raised if the changelog anchor string cannot be found""" current_date = datetime.now().strftime("%Y-%m-%d")