Skip to content

Commit fcb444c

Browse files
authored
Merge branch 'main' into migrate-off-bazel
2 parents 8b182cf + c9e1b8d commit fcb444c

File tree

551 files changed

+133773
-3869
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

551 files changed

+133773
-3869
lines changed

.generator/Dockerfile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,10 @@ COPY .generator/requirements.in .
123123
RUN python3.9 -m pip install -r requirements.in
124124
RUN python3.9 -m pip install /synthtool
125125

126+
# Install build which is used to get the metadata of package config files.
127+
COPY .generator/requirements.in .
128+
RUN python3.9 -m pip install -r requirements.in
129+
126130
# Copy the CLI script into the container.
127131
COPY .generator/cli.py .
128132
RUN chmod a+rx ./cli.py

.generator/cli.py

Lines changed: 65 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,13 @@
2323
import subprocess
2424
import sys
2525
import tempfile
26+
import yaml
2627
from datetime import datetime
2728
from pathlib import Path
2829
from typing import Dict, List
29-
30+
import build.util
3031
import parse_googleapis_content
31-
import yaml
32+
3233

3334
try:
3435
import synthtool
@@ -334,7 +335,6 @@ def _run_nox_sessions(library_id: str, repo: str):
334335
"unit-3.9",
335336
"unit-3.13",
336337
"docs",
337-
"system-3.13",
338338
"lint",
339339
"lint_setup_py",
340340
"mypy-3.13",
@@ -450,12 +450,54 @@ def _verify_library_namespace(library_id: str, repo: str):
450450
)
451451

452452

453+
def _get_library_dist_name(library_id: str, repo: str) -> str:
454+
"""
455+
Gets the package name by programmatically building the metadata.
456+
457+
Args:
458+
library_id: id of the library.
459+
repo: This directory will contain all directories that make up a
460+
library, the .librarian folder, and any global file declared in
461+
the config.yaml.
462+
463+
Returns:
464+
str: The library name string if found, otherwise None.
465+
"""
466+
library_path = f"{repo}/packages/{library_id}"
467+
metadata = build.util.project_wheel_metadata(library_path)
468+
return metadata.get("name")
469+
470+
471+
def _verify_library_dist_name(library_id: str, repo: str):
472+
"""Verifies the library distribution name against its config files.
473+
474+
This function ensures that:
475+
1. At least one of `setup.py` or `pyproject.toml` exists and is valid.
476+
2. Any existing config file's 'name' property matches the `library_id`.
477+
478+
Args:
479+
library_id: id of the library.
480+
repo: This directory will contain all directories that make up a
481+
library, the .librarian folder, and any global file declared in
482+
the config.yaml.
483+
484+
Raises:
485+
ValueError: If a name in an existing config file does not match the `library_id`.
486+
"""
487+
dist_name = _get_library_dist_name(library_id, repo)
488+
if dist_name != library_id:
489+
raise ValueError(
490+
f"The distribution name `{dist_name}` does not match the folder `{library_id}`."
491+
)
492+
493+
453494
def handle_build(librarian: str = LIBRARIAN_DIR, repo: str = REPO_DIR):
454495
"""The main coordinator for validating client library generation."""
455496
try:
456497
request_data = _read_json_file(f"{librarian}/{BUILD_REQUEST_FILE}")
457498
library_id = _get_library_id(request_data)
458499
_verify_library_namespace(library_id, repo)
500+
_verify_library_dist_name(library_id, repo)
459501
_run_nox_sessions(library_id, repo)
460502
except Exception as e:
461503
raise ValueError("Build failed.") from e
@@ -750,6 +792,12 @@ def handle_release_init(
750792
the config.yaml.
751793
output(str): Path to the directory in the container where modified
752794
code should be placed.
795+
796+
Raises:
797+
ValueError: if the version in `release-init-request.json` is
798+
the same as the version in state.yaml or if the
799+
`release-init-request.json` file in the given
800+
librarian directory cannot be read.
753801
"""
754802

755803
try:
@@ -772,20 +820,25 @@ def handle_release_init(
772820
library_id = library_release_data["id"]
773821
library_changes = library_release_data["changes"]
774822
path_to_library = f"packages/{library_id}"
775-
_update_version_for_library(repo, output, path_to_library, version)
776823

777824
# Get previous version from state.yaml
778825
previous_version = _get_previous_version(library_id, librarian)
779-
if previous_version != version:
780-
_update_changelog_for_library(
781-
repo,
782-
output,
783-
library_changes,
784-
version,
785-
previous_version,
786-
library_id,
826+
if previous_version == version:
827+
raise ValueError(
828+
f"The version in {RELEASE_INIT_REQUEST_FILE} is the same as the version in {STATE_YAML_FILE}\n"
829+
f"{library_id} version: {previous_version}\n"
787830
)
788831

832+
_update_version_for_library(repo, output, path_to_library, version)
833+
_update_changelog_for_library(
834+
repo,
835+
output,
836+
library_changes,
837+
version,
838+
previous_version,
839+
library_id,
840+
)
841+
789842
except Exception as e:
790843
raise ValueError(f"Release init failed: {e}") from e
791844

.generator/requirements-test.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,4 @@ pytest-cov
1717
pytest-mock
1818
gcp-synthtool @ git+https://github.com/googleapis/synthtool@5aa438a342707842d11fbbb302c6277fbf9e4655
1919
starlark-pyo3>=2025.1
20+
build

.generator/requirements.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@ click
22
gapic-generator
33
nox
44
starlark-pyo3>=2025.1
5+
build

.generator/test_cli.py

Lines changed: 56 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
_clean_up_files_after_post_processing,
3737
_copy_files_needed_for_post_processing,
3838
_create_main_version_header,
39+
_get_library_dist_name,
3940
_determine_library_namespace,
4041
_get_library_id,
4142
_get_libraries_to_prepare_for_release,
@@ -50,6 +51,7 @@
5051
_update_changelog_for_library,
5152
_update_global_changelog,
5253
_update_version_for_library,
54+
_verify_library_dist_name,
5355
_verify_library_namespace,
5456
_write_json_file,
5557
_write_text_file,
@@ -364,7 +366,6 @@ def test_run_nox_sessions_success(mocker, mock_generate_request_data_for_nox):
364366
"unit-3.9",
365367
"unit-3.13",
366368
"docs",
367-
"system-3.13",
368369
"lint",
369370
"lint_setup_py",
370371
"mypy-3.13",
@@ -377,7 +378,6 @@ def test_run_nox_sessions_success(mocker, mock_generate_request_data_for_nox):
377378
mocker.call("unit-3.9", "mock-library", "repo"),
378379
mocker.call("unit-3.13", "mock-library", "repo"),
379380
mocker.call("docs", "mock-library", "repo"),
380-
mocker.call("system-3.13", "mock-library", "repo"),
381381
mocker.call("lint", "mock-library", "repo"),
382382
mocker.call("lint_setup_py", "mock-library", "repo"),
383383
mocker.call("mypy-3.13", "mock-library", "repo"),
@@ -430,7 +430,8 @@ def test_handle_build_success(caplog, mocker, mock_build_request_file):
430430
caplog.set_level(logging.INFO)
431431

432432
mocker.patch("cli._run_nox_sessions")
433-
mocker.patch("cli._verify_library_namespace", return_value=True)
433+
mocker.patch("cli._verify_library_namespace")
434+
mocker.patch("cli._verify_library_dist_name")
434435
handle_build()
435436

436437
assert "'build' command executed." in caplog.text
@@ -507,14 +508,44 @@ def test_handle_release_init_success(mocker, mock_release_init_request_file):
507508
handle_release_init()
508509

509510

510-
def test_handle_release_init_fail():
511+
def test_handle_release_init_fail_value_error_file():
511512
"""
512513
Tests that handle_release_init fails to read `librarian/release-init-request.json`.
513514
"""
514-
with pytest.raises(ValueError):
515+
with pytest.raises(ValueError, match="No such file or directory"):
515516
handle_release_init()
516517

517518

519+
def test_handle_release_init_fail_value_error_version(mocker):
520+
m = mock_open()
521+
522+
mock_release_init_request_content = {
523+
"libraries": [
524+
{
525+
"id": "google-cloud-language",
526+
"apis": [{"path": "google/cloud/language/v1"}],
527+
"release_triggered": True,
528+
"version": "1.2.2",
529+
"changes": [],
530+
},
531+
]
532+
}
533+
with unittest.mock.patch("cli.open", m):
534+
mocker.patch(
535+
"cli._get_libraries_to_prepare_for_release",
536+
return_value=mock_release_init_request_content["libraries"],
537+
)
538+
mocker.patch("cli._get_previous_version", return_value="1.2.2")
539+
mocker.patch("cli._process_changelog", return_value=None)
540+
mocker.patch(
541+
"cli._read_json_file", return_value=mock_release_init_request_content
542+
)
543+
with pytest.raises(
544+
ValueError, match="is the same as the version in state.yaml"
545+
):
546+
handle_release_init()
547+
548+
518549
def test_read_valid_text_file(mocker):
519550
"""Tests reading a valid text file."""
520551
mock_content = "some text"
@@ -797,6 +828,26 @@ def test_determine_library_namespace_fails_not_subpath():
797828
_determine_library_namespace(gapic_parent_path, pkg_root_path)
798829

799830

831+
def test_get_library_dist_name_success(mocker):
832+
mock_metadata = {"name": "my-lib", "version": "1.0.0"}
833+
mocker.patch("build.util.project_wheel_metadata", return_value=mock_metadata)
834+
assert _get_library_dist_name("my-lib", "repo") == "my-lib"
835+
836+
837+
def test_verify_library_dist_name_setup_success(mocker):
838+
"""Tests success when a library distribution name in setup.py is valid."""
839+
mock_setup_file = mocker.patch("cli._get_library_dist_name", return_value="my-lib")
840+
_verify_library_dist_name("my-lib", "repo")
841+
mock_setup_file.assert_called_once_with("my-lib", "repo")
842+
843+
844+
def test_verify_library_dist_name_fail(mocker):
845+
"""Tests failure when a library-id does not match the libary distribution name."""
846+
mocker.patch("cli._get_library_dist_name", return_value="invalid-lib")
847+
with pytest.raises(ValueError):
848+
_verify_library_dist_name("my-lib", "repo")
849+
850+
800851
def test_verify_library_namespace_success_valid(mocker, mock_path_class):
801852
"""Tests success when a single valid namespace is found."""
802853
# 1. Get the mock instance from the mock class's return_value

.github/CODEOWNERS

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
# Code owners file.
22
# This file controls who is tagged for review for any given pull request.
33

4-
* @googleapis/python-core-client-libraries
4+
# Default owner for all directories not owned by others
5+
* @googleapis/python-core-client-libraries @googleapis/cloud-sdk-librarian-team
56

6-
/.generator/ @googleapis/cloud-sdk-librarian-team
7-
/.librarian/ @googleapis/cloud-sdk-librarian-team
7+
# Packages onboarded to librarian require review from both groups
8+
/packages/google-cloud-dlp/ @googleapis/python-core-client-libraries
9+
/packages/google-cloud-dlp/ @googleapis/cloud-sdk-librarian-team
10+
11+
/packages/google-cloud-bigquery-storage/ @googleapis/api-bigquery

.github/workflows/configure_release_please.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ on:
2323
branches:
2424
- main
2525

26+
# Allows you to run this workflow manually from the Actions tab
27+
workflow_dispatch:
28+
2629
permissions:
2730
contents: read
2831

.kokoro/system.sh

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -38,21 +38,35 @@ pwd
3838
# A file for running system tests
3939
system_test_script="${PROJECT_ROOT}/.kokoro/system-single.sh"
4040

41+
# This is needed in order for `git diff` to succeed
42+
git config --global --add safe.directory $(realpath .)
43+
4144
# Run system tests for each package with directory packages/*/tests/system
4245
for dir in `find 'packages' -type d -wholename 'packages/*/tests/system'`; do
4346
# Get the path to the package by removing the suffix /tests/system
4447
package=$(echo $dir | cut -f -2 -d '/')
45-
echo "Running system tests for ${package}"
46-
pushd ${package}
47-
# Temporarily allow failure.
48+
49+
files_to_check=${package}/CHANGELOG.md
50+
51+
echo "checking changes with 'git diff "${KOKORO_GITHUB_PULL_REQUEST_TARGET_BRANCH}...${KOKORO_GITHUB_PULL_REQUEST_COMMIT}" -- ${files_to_check}'"
4852
set +e
49-
${system_test_script}
50-
ret=$?
53+
package_modified=$(git diff "${KOKORO_GITHUB_PULL_REQUEST_TARGET_BRANCH}...${KOKORO_GITHUB_PULL_REQUEST_COMMIT}" -- ${files_to_check} | wc -l)
5154
set -e
52-
if [ ${ret} -ne 0 ]; then
53-
RETVAL=${ret}
55+
if [[ "${package_modified}" -eq 0 ]]; then
56+
echo "no change detected in ${files_to_check}, skipping"
57+
else
58+
echo "change detected in ${files_to_check}"
59+
echo "Running system tests for ${package}"
60+
pushd ${package}
61+
# Temporarily allow failure.
62+
set +e
63+
${system_test_script}
64+
ret=$?
65+
set -e
66+
if [ ${ret} -ne 0 ]; then
67+
RETVAL=${ret}
68+
fi
69+
popd
5470
fi
55-
popd
5671
done
57-
5872
exit ${RETVAL}

.librarian/generator-input/client-post-processing/add-missing-dependencies-to-setup-py-constraints.yaml

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,3 +161,43 @@ replacements:
161161
"google-cloud-org-policy >= 1.0.0, <2.0.0",
162162
"proto-plus >= 1.22.3, <2.0.0",
163163
count: 1
164+
- paths: [
165+
packages/google-shopping-merchant-notifications/setup.py
166+
]
167+
before: |
168+
dependencies = \[
169+
"google-api-core\[grpc\] >= 1.34.1, <3.0.0,!=2.0.*,!=2.1.*,!=2.2.*,!=2.3.*,!=2.4.*,!=2.5.*,!=2.6.*,!=2.7.*,!=2.8.*,!=2.9.*,!=2.10.*",
170+
# Exclude incompatible versions of `google-auth`
171+
# See https://github.com/googleapis/google-cloud-python/issues/12364
172+
"google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0",
173+
"proto-plus >= 1.22.3, <2.0.0",
174+
"proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'",
175+
"protobuf>=3.20.2,<7.0.0,!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5",
176+
\]
177+
after: |
178+
dependencies = [
179+
"google-api-core[grpc] >= 1.34.1, <3.0.0,!=2.0.*,!=2.1.*,!=2.2.*,!=2.3.*,!=2.4.*,!=2.5.*,!=2.6.*,!=2.7.*,!=2.8.*,!=2.9.*,!=2.10.*",
180+
# Exclude incompatible versions of `google-auth`
181+
# See https://github.com/googleapis/google-cloud-python/issues/12364
182+
"google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0",
183+
"proto-plus >= 1.22.3, <2.0.0",
184+
"proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'",
185+
"protobuf>=3.20.2,<7.0.0,!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5",
186+
"google-shopping-type >= 1.0.0, <2.0.0",
187+
]
188+
count: 1
189+
- paths: [
190+
packages/google-shopping-merchant-notifications/testing/constraints-3.7.txt
191+
]
192+
before: |
193+
google-api-core==1.34.1
194+
google-auth==2.14.1
195+
proto-plus==1.22.3
196+
protobuf==3.20.2
197+
after: |
198+
google-api-core==1.34.1
199+
google-auth==2.14.1
200+
proto-plus==1.22.3
201+
google-shopping-type==1.0.0
202+
protobuf==3.20.2
203+
count: 1

0 commit comments

Comments
 (0)