diff --git a/.generator/cli.py b/.generator/cli.py index ef68e6d7b86e..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,7 +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. + 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( @@ -1373,6 +1381,11 @@ def _update_changelog_for_library( ) _write_text_file(changelog_dest, updated_content) + 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 +1437,6 @@ def handle_release_init( ) if is_mono_repo: - # only a mono repo has a global changelog _update_global_changelog( f"{repo}/CHANGELOG.md", @@ -1449,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( @@ -1462,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: diff --git a/.generator/test_cli.py b/.generator/test_cli.py index 67be0b13d1f4..7b0b17ac069f 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,60 @@ 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 +""" + 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=True, + ) -## [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) + 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_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 """ - 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", + 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():