Skip to content

Commit a3d2344

Browse files
authored
chore(librarian): exclude version files under tests directory (#14862)
This PR fixes an issue where `librarian release stage` fails for libraries when version files exist under test directories and are not expected to be updated. See the following stack trace for `gapic-generator-python` when running `librarian release stage`. ``` partheniou@partheniou-vm-3:~/git/gapic-generator-python$ librarian release stage time=2025-11-08T14:22:44.752Z level=INFO msg="temporary working directory" dir=/tmp/librarian-1630479680 time=2025-11-08T14:22:44.752Z level=INFO msg="repo not specified, using current working directory as repo root" path=/usr/local/google/home/partheniou/git/gapic-generator-python time=2025-11-08T14:22:44.752Z level=INFO msg="opening repository" dir=/usr/local/google/home/partheniou/git/gapic-generator-python time=2025-11-08T14:22:44.956Z level=INFO msg="source not specified, skipping service config population" time=2025-11-08T14:22:44.956Z level=INFO msg="config.yaml not found, proceeding" time=2025-11-08T14:22:44.957Z level=INFO msg="staging a release" dir=/tmp/librarian-1630479680/output time=2025-11-08T14:22:44.973Z level=INFO msg="updating library to the next version" library=gapic-generator currentVersion=1.29.0 nextVersion=1.30.0 time=2025-11-08T14:22:44.974Z level=INFO msg="=== Docker start ===============================================================" time=2025-11-08T14:22:44.974Z level=INFO msg="/usr/bin/docker run --rm -v /usr/local/google/home/partheniou/git/gapic-generator-python/.librarian:/librarian -v /usr/local/google/home/partheniou/git/gapic-generator-python:/repo:ro -v /tmp/librarian-1630479680/output:/output --user 814163:89939 us-central1-docker.pkg.dev/cloud-sdk-librarian-prod/images-prod/python-librarian-generator:latest release-stage --librarian=/librarian --repo=/repo --output=/output" time=2025-11-08T14:22:44.974Z level=INFO msg=-------------------------------------------------------------------------------- 2025-11-08 14:22:45,791 synthtool [CRITICAL] > You are running the synthesis script directly, this will be disabled in a future release of Synthtool. Please use python3 -m synthtool instead. 2025-11-08 14:22:45,990 synthtool [DEBUG] > Using local templates at /synthtool/synthtool/gcp/templates 2025-11-08 14:22:45,997 synthtool [DEBUG] > Using local templates at /synthtool/synthtool/gcp/templates Traceback (most recent call last): File "/app/./cli.py", line 1497, in handle_release_stage _update_version_for_library(repo, output, path_to_library, version) ~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/app/./cli.py", line 1251, in _update_version_for_library _write_json_file(output_path, metadata_contents) ~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/app/./cli.py", line 114, in _write_json_file with open(path, "w") as f: ~~~~^^^^^^^^^^^ PermissionError: [Errno 13] Permission denied: '/output/tests/integration/goldens/redis_selective/samples/generated_samples/snippet_metadata_google.cloud.redis.v1.json' The above exception was the direct cause of the following exception: Traceback (most recent call last): File "/app/./cli.py", line 1592, in <module> args.func(librarian=args.librarian, repo=args.repo, output=args.output) ~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/app/./cli.py", line 1509, in handle_release_stage raise ValueError(f"Release stage failed: {e}") from e ValueError: Release stage failed: [Errno 13] Permission denied: '/output/tests/integration/goldens/redis_selective/samples/generated_samples/snippet_metadata_google.cloud.redis.v1.json' time=2025-11-08T14:22:46.419Z level=INFO msg="=== Docker end =================================================================" time=2025-11-08T14:22:46.419Z level=ERROR msg="librarian command failed" err="exit status 1" ```
1 parent 3c265a4 commit a3d2344

File tree

2 files changed

+18
-14
lines changed

2 files changed

+18
-14
lines changed

.generator/cli.py

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1199,7 +1199,8 @@ def _update_version_for_library(
11991199

12001200
# Find and update version.py or gapic_version.py files
12011201
search_base = Path(f"{repo}/{path_to_library}")
1202-
version_files = list(search_base.rglob("**/gapic_version.py"))
1202+
version_files = []
1203+
patterns = ["**/gapic_version.py", "**/version.py"]
12031204
excluded_dirs = {
12041205
".nox",
12051206
".venv",
@@ -1209,14 +1210,16 @@ def _update_version_for_library(
12091210
"build",
12101211
"dist",
12111212
"__pycache__",
1213+
"tests",
12121214
}
1213-
version_files.extend(
1214-
[
1215-
p
1216-
for p in search_base.rglob("**/version.py")
1217-
if not any(part in excluded_dirs for part in p.parts)
1218-
]
1219-
)
1215+
for pattern in patterns:
1216+
version_files.extend(
1217+
[
1218+
p
1219+
for p in search_base.rglob(pattern)
1220+
if not any(part in excluded_dirs for part in p.parts)
1221+
]
1222+
)
12201223

12211224
if not version_files:
12221225
# Fallback to `pyproject.toml`` or `setup.py``. Proto-only libraries have
@@ -1238,8 +1241,8 @@ def _update_version_for_library(
12381241
_write_text_file(output_path, updated_content)
12391242

12401243
# Find and update snippet_metadata.json files
1241-
snippet_metadata_files = Path(f"{repo}/{path_to_library}").rglob(
1242-
"samples/**/*snippet*.json"
1244+
snippet_metadata_files = Path(f"{repo}/{path_to_library}/samples").rglob(
1245+
"**/*snippet*.json"
12431246
)
12441247
for metadata_file in snippet_metadata_files:
12451248
output_path = f"{output}/{metadata_file.relative_to(repo)}"

.generator/test_cli.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1037,18 +1037,19 @@ def test_update_version_for_library_success_gapic(mocker):
10371037

10381038
mock_rglob = mocker.patch("pathlib.Path.rglob")
10391039
mock_rglob.side_effect = [
1040-
[pathlib.Path("repo/gapic_version.py")], # 1st call (gapic_version.py)
1040+
[pathlib.Path("repo/gapic_version.py"), pathlib.Path("repo/tests/gapic_version.py")], # 1st call (gapic_version.py)
10411041
[pathlib.Path("repo/types/version.py")], # 2nd call (types/version.py).
10421042
[pathlib.Path("repo/samples/snippet_metadata.json")], # 3rd call (snippets)
10431043
]
1044-
mock_rglob = mocker.patch("cli._read_text_file")
1045-
mock_rglob.side_effect = [
1044+
mock_read_text_file = mocker.patch("cli._read_text_file")
1045+
mock_read_text_file.side_effect = [
10461046
mock_content, # 1st call (gapic_version.py)
10471047
# Do not process version files in the `types` directory as some
10481048
# GAPIC libraries have `version.py` which are generated from
10491049
# `version.proto` and do not include SDK versions.
10501050
# Leave the content as empty because it doesn't contain version information
1051-
"", # 2nd call (types/version.py)
1051+
"", # 2nd call (tests/gapic_version.py)
1052+
"", # 3rd call (types/version.py)
10521053
]
10531054

10541055
with unittest.mock.patch("cli.open", m):

0 commit comments

Comments
 (0)