Skip to content

Commit 565f6fb

Browse files
Merge branch 'googleapis:main' into grpc-cert-rotation
2 parents a9e45af + 89cfe85 commit 565f6fb

297 files changed

Lines changed: 4638 additions & 2853 deletions

File tree

Some content is hidden

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

.github/workflows/import-profiler.yml

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,16 @@ jobs:
1616
import-profile:
1717
runs-on: ubuntu-latest
1818
timeout-minutes: 60
19+
strategy:
20+
fail-fast: false
21+
matrix:
22+
shard: [0, 1, 2, 3, 4, 5, 6, 7] # 8 parallel shards
23+
name: import-profile (Shard ${{ matrix.shard }})
1924
steps:
2025
- name: Checkout
2126
uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6
2227
with:
23-
fetch-depth: 2
28+
fetch-depth: 0 # Fetch git history to find changed packages
2429
persist-credentials: false
2530
- name: Setup Python
2631
uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6
@@ -41,5 +46,44 @@ jobs:
4146
PY_VERSION: "3.15"
4247
# Workaround: Allows libcst to compile on Python 3.15+ while PyO3 catches up
4348
PYO3_USE_ABI3_FORWARD_COMPATIBILITY: "1"
49+
SHARD_INDEX: ${{ matrix.shard }}
50+
TOTAL_SHARDS: 8
4451
run: |
45-
ci/run_conditional_tests.sh
52+
TARGET_BRANCH=${TARGET_BRANCH:-main}
53+
git fetch origin "${TARGET_BRANCH}" --deepen=200 || true
54+
55+
# Get unique list of modified packages under packages/
56+
modified_packages=$(git diff --name-only origin/"${TARGET_BRANCH}"... | grep '^packages/' | cut -d/ -f1,2 | sort -u)
57+
58+
# Filter packages assigned to this specific shard index
59+
idx=0
60+
packages_to_test=""
61+
for pkg in $modified_packages; do
62+
if [ -d "$pkg" ]; then
63+
if [ "$((idx % TOTAL_SHARDS))" -eq "${SHARD_INDEX}" ]; then
64+
packages_to_test="$packages_to_test $pkg"
65+
fi
66+
idx=$((idx + 1))
67+
fi
68+
done
69+
70+
# Run tests on the assigned packages
71+
if [ -n "$packages_to_test" ]; then
72+
echo "Shard ${{ matrix.shard }} running packages: $packages_to_test"
73+
PACKAGE_LIST="$packages_to_test" ci/run_conditional_tests.sh
74+
else
75+
echo "No packages assigned to Shard ${{ matrix.shard }}."
76+
fi
77+
78+
all-import-profiles:
79+
needs: import-profile
80+
if: always()
81+
runs-on: ubuntu-latest
82+
steps:
83+
- name: Check import profile results
84+
run: |
85+
if [[ "${{ needs.import-profile.result }}" != "success" && "${{ needs.import-profile.result }}" != "skipped" ]]; then
86+
echo "Import profiles failed"
87+
exit 1
88+
fi
89+
echo "All import profiles passed or were skipped"

.github/workflows/unittest.yml

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ env:
1818
NOX_ENVDIR: "/tmp/shared_nox_envs"
1919
NOX_DEFAULT_VENV_BACKEND: "uv"
2020
UV_VENV_SEED: "1"
21+
UV_PRERELEASE: "allow"
2122
# Note: PARALLEL_WORKERS must remain "1" for unit tests because running pytest concurrently
2223
# on the same runner VM can cause socket/IPC/process deadlocks across packages.
2324
PARALLEL_WORKERS: "1"
@@ -83,7 +84,7 @@ jobs:
8384
strategy:
8485
fail-fast: true
8586
matrix:
86-
python: ['3.10', "3.11", "3.12", "3.13", "3.14"]
87+
python: ["3.10", "3.11", "3.12", "3.13", "3.14", "3.15"]
8788
package_shard: ${{ fromJson(needs.initialize.outputs.matrix) }}
8889
name: ${{ matrix.package_shard.is_sharded && format('unit ({0}, {1})', matrix.python, matrix.package_shard.name) || format('unit ({0})', matrix.python) }}
8990
steps:
@@ -100,10 +101,40 @@ jobs:
100101
with:
101102
python-version: ${{ matrix.python }}
102103
cache: 'pip'
103-
- name: Install nox
104+
allow-prereleases: true
105+
- name: Setup uv
106+
uses: astral-sh/setup-uv@d4b2f3b6ecc6e67c4457f6d3e41ec42d3d0fcb86 # v5
107+
with:
108+
enable-cache: true
109+
cache-dependency-glob: 'packages/**/testing/constraints*.txt'
110+
- name: Install nox and nox-uv
104111
run: |
105-
python -m pip install --upgrade setuptools pip wheel
106-
python -m pip install nox uv
112+
uv pip install --system nox nox-uv
113+
# Caches local wheels for Python 3.15+ to avoid repeatedly downloading or building heavy libraries.
114+
# Follow https://github.com/grpc/grpc/issues/41010 for updates.
115+
- name: Cache Built Python 3.15 Wheels
116+
if: matrix.python == '3.15'
117+
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4
118+
with:
119+
path: .uv-wheel-cache
120+
key: ${{ runner.os }}-uv-wheels-3.15-${{ hashFiles('packages/**/testing/constraints*.txt') }}
121+
restore-keys: |
122+
${{ runner.os }}-uv-wheels-3.15-
123+
# TODO: Remove this step once official Python 3.15 wheels for grpcio are published to PyPI.
124+
# See https://github.com/grpc/grpc/issues/41010#issuecomment-4848264910 for details.
125+
- name: Install grpcio wheel for Python 3.15
126+
if: matrix.python == '3.15'
127+
run: |
128+
mkdir -p .uv-wheel-cache
129+
WHEEL_FILE=".uv-wheel-cache/grpcio-1.83.0.dev0-cp315-cp315-manylinux2014_x86_64.manylinux_2_17_x86_64.whl"
130+
if [ ! -f "$WHEEL_FILE" ]; then
131+
curl -L "https://packages.grpc.io/archive/2026/06/5ccdab32010f762634e1082d19be53cf60458456-b37e49c7-5e62-4cbe-870a-c599bb907b04/python/grpcio/grpcio-1.83.0.dev0-cp315-cp315-manylinux2014_x86_64.manylinux_2_17_x86_64.whl" -o "$WHEEL_FILE"
132+
fi
133+
echo "d7706633cd5d97a8b8d3c6ed36c5940722a9b5cbb47f0d10bc433ee27af36ff0 $WHEEL_FILE" | sha256sum -c
134+
uv pip install --system "$WHEEL_FILE"
135+
echo "UV_FIND_LINKS=${{ github.workspace }}/.uv-wheel-cache" >> $GITHUB_ENV
136+
echo "UV_CACHE_DIR=${{ github.workspace }}/.uv-wheel-cache" >> $GITHUB_ENV
137+
echo "UV_PRERELEASE=allow" >> $GITHUB_ENV
107138
- name: Run unit tests for ${{ matrix.package_shard.description }}
108139
env:
109140
BUILD_TYPE: presubmit

.kokoro/system.sh

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -263,16 +263,25 @@ for path in `find 'packages' \
263263
files_to_check=("${package_path}")
264264
fi
265265

266-
echo "checking changes with 'git diff ${KOKORO_GITHUB_PULL_REQUEST_TARGET_BRANCH}...${KOKORO_GITHUB_PULL_REQUEST_COMMIT} -- ${files_to_check[*]}'"
267266
set +e
268-
# Passing the array expanded as arguments to git diff
267+
# Passing the array expanded as arguments to git diff.
269268
package_modified=$(git diff "${KOKORO_GITHUB_PULL_REQUEST_TARGET_BRANCH}...${KOKORO_GITHUB_PULL_REQUEST_COMMIT}" -- "${files_to_check[@]}" | wc -l)
270269
set -e
271270

272-
if [[ "${package_modified}" -gt 0 || "$KOKORO_BUILD_ARTIFACTS_SUBDIR" == *"continuous"* ]]; then
271+
states=()
272+
[[ "${package_modified}" -gt 0 ]] && states+=("changed")
273+
[[ "$KOKORO_BUILD_ARTIFACTS_SUBDIR" == *"continuous"* ]] && states+=("continuous")
274+
275+
# Join states with a comma
276+
state_str=$(IFS=, ; echo "${states[*]}")
277+
278+
commit_hash="${KOKORO_GITHUB_PULL_REQUEST_COMMIT:-HEAD}"
279+
280+
if [[ ${#states[@]} -gt 0 ]]; then
281+
printf "TEST %-20s %-40s %s\n" "[${state_str}]" "${package_name}" "${commit_hash}"
273282
PACKAGES_TO_TEST+=("$package_name")
274283
else
275-
echo "No changes in ${package_name} and not a continuous build, skipping."
284+
printf "SKIP %-20s %-40s %s\n" "[no_changes]" "${package_name}" "${commit_hash}"
276285
fi
277286
done
278287

.librarian/generator-input/client-post-processing/bigquery-storage-integration.yaml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -520,3 +520,17 @@ replacements:
520520
bigquery_storage_v1alpha/types_\n\n
521521
Changelog
522522
count: 1
523+
- paths: [
524+
packages/google-cloud-bigquery-storage/noxfile.py,
525+
]
526+
before: |
527+
# Install all test dependencies, then install this package in-place.\n
528+
constraints_path = str\(
529+
after: |
530+
# Install all test dependencies, then install this package in-place.
531+
532+
if session.python == "3.15":
533+
session.skip("Skipping 3.15 until wheels are available for pyarrow.")
534+
535+
constraints_path = str(
536+
count: 1

.librarian/generator-input/client-post-processing/storage-integration.yaml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -819,3 +819,18 @@ replacements:
819819
*session.posargs,
820820
)
821821
count: 1
822+
- paths: [
823+
packages/google-cloud-storage/noxfile.py,
824+
]
825+
before: |
826+
# Install all test dependencies, then install this package in-place.\n
827+
constraints_path = str\(
828+
after: |
829+
# Install all test dependencies, then install this package in-place.
830+
831+
if session.python == "3.15":
832+
session.skip(
833+
"Skipping 3.15 until compatible wheels are available for google-crc32c"
834+
)
835+
constraints_path = str(
836+
count: 1

ci/report_coverage.sh

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,6 @@ MAX_JOBS=$(nproc)
2626

2727
mkdir -p "${LOG_DIR}"
2828

29-
if [ ! -d "${RESULTS_DIR}" ]; then
30-
echo "Error: No coverage results found in ${RESULTS_DIR}."
31-
exit 1
32-
fi
33-
34-
# Unzip any zipped coverage results
35-
find "$RESULTS_DIR" -type f -name '*.zip' -print0 | xargs -0 -P "${MAX_JOBS}" -I {} unzip -q -o {} -d "$RESULTS_DIR"
36-
3729
# Identify modified packages
3830
BUILD_TYPE="${BUILD_TYPE:-presubmit}"
3931
TARGET_BRANCH="${TARGET_BRANCH:-main}"
@@ -51,13 +43,36 @@ else
5143
modified_packages=$(git diff --name-only HEAD~1 -- ${PACKAGE_DIRS} 2>/dev/null | cut -d/ -f1,2 | sort -u)
5244
fi
5345

46+
# Check if any modified package requires coverage
47+
requires_coverage=false
48+
for pkg in ${modified_packages}; do
49+
if [ -f "${pkg}/.coveragerc" ] && grep -Eq "fail_under\s*=\s*0" "${pkg}/.coveragerc"; then
50+
continue
51+
fi
52+
requires_coverage=true
53+
break
54+
done
55+
56+
if [ ! -d "${RESULTS_DIR}" ] || [ -z "$(ls -A "${RESULTS_DIR}" 2>/dev/null)" ]; then
57+
if [ "${requires_coverage}" = "true" ]; then
58+
echo "Error: No coverage results found in ${RESULTS_DIR}, but some modified packages require coverage."
59+
exit 1
60+
else
61+
echo "No coverage results found, but no modified packages require coverage."
62+
exit 0
63+
fi
64+
fi
65+
66+
# Unzip any zipped coverage results
67+
find "$RESULTS_DIR" -type f -name '*.zip' -print0 | xargs -0 -P "${MAX_JOBS}" -I {} unzip -q -o {} -d "$RESULTS_DIR"
68+
5469
# Function to report coverage for a single package
5570
report_package_coverage() {
5671
local pkg=$1
5772
local pkg_name_clean=$(echo "${pkg}" | sed 's|/$||' | sed 's|/|_|g')
5873
local pkg_log="${LOG_DIR}/${pkg_name_clean}.log"
5974
local pkg_status="${LOG_DIR}/${pkg_name_clean}.status"
60-
75+
6176
# Use /dev/shm for the combined coverage file to reduce disk I/O
6277
local pkg_coverage_db="/dev/shm/.coverage.${pkg_name_clean}"
6378

@@ -104,7 +119,7 @@ report_package_coverage() {
104119
echo "No .coveragerc found for ${pkg}, enforcing default" >> "${pkg_log}"
105120
COVERAGE_FILE="${pkg_coverage_db}" coverage report --include="$PWD/**" --fail-under="${DEFAULT_FAIL_UNDER}" >> "${pkg_log}" 2>&1
106121
fi
107-
122+
108123
echo $? > "${pkg_status}"
109124
popd > /dev/null
110125
)

ci/run_single_test.sh

Lines changed: 65 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,11 @@ case ${TEST_TYPE} in
9090
nox -s unit-3.14
9191
retval=$?
9292
;;
93+
"3.15")
94+
# This is needed to speed up builds
95+
nox --force-venv-backend uv -s unit-3.15
96+
retval=$?
97+
;;
9398
*)
9499
echo "unsupported PY_VERSION"
95100
exit 1
@@ -98,13 +103,35 @@ case ${TEST_TYPE} in
98103
;;
99104
import_profile)
100105
if [ -f setup.py ] || [ -f pyproject.toml ]; then
106+
PACKAGE_NAME=$(basename $(pwd))
107+
108+
# TODO(https://github.com/googleapis/google-cloud-python/issues/18035):
109+
# Remove this skip once Python 3.15 is officially released and upstream binary wheels
110+
# (e.g. numpy, pyarrow, pandas, geopandas, pikepdf) are published on PyPI.
111+
# Packages with heavy C/Rust dependencies attempt full source compilation on pre-release Python,
112+
# taking 5-10+ minutes before failing due to unreleased CPython 3.15 C-API changes.
113+
if [[ "${PY_VERSION}" == "3.15"* ]]; then
114+
UNSUPPORTED_PRE_RELEASE_PACKAGES=(
115+
"bigframes"
116+
"pandas-gbq"
117+
"google-cloud-documentai-toolbox"
118+
"db-dtypes"
119+
"bigquery-magics"
120+
)
121+
for unsupported in "${UNSUPPORTED_PRE_RELEASE_PACKAGES[@]}"; do
122+
if [ "${PACKAGE_NAME}" = "${unsupported}" ]; then
123+
echo "WARNING: Skipping import_profile for ${PACKAGE_NAME}: package has heavy C/Rust dependencies not yet supported on pre-release Python ${PY_VERSION}."
124+
exit 0
125+
fi
126+
done
127+
fi
128+
101129
echo "Creating temporary virtualenv for import profile..."
102130
python3 -m venv .venv-profiler
103131
source .venv-profiler/bin/activate
104132
export PYO3_USE_ABI3_FORWARD_COMPATIBILITY=1
105133
python -m pip install --upgrade pip setuptools
106134

107-
PACKAGE_NAME=$(basename $(pwd))
108135
PROFILER_TEMP_DIR=$(mktemp -d)
109136
cp ../../scripts/import_profiler/profiler.py "${PROFILER_TEMP_DIR}/profiler.py"
110137
PROFILER_SCRIPT="${PROFILER_TEMP_DIR}/profiler.py"
@@ -121,13 +148,26 @@ case ${TEST_TYPE} in
121148
WORKTREE_DIR=$(mktemp -d)
122149
rmdir "${WORKTREE_DIR}"
123150
if git worktree add "${WORKTREE_DIR}" "${BASELINE_COMMIT}" 2>/dev/null; then
124-
(
151+
if ! (
125152
cd "${WORKTREE_DIR}/${REPO_PREFIX}"
126153
if [ -f setup.py ] || [ -f pyproject.toml ]; then
127-
pip install -e .
128-
python "${PROFILER_SCRIPT}" --package "${PACKAGE_NAME}" --iterations 11 --csv "${BASELINE_CSV}"
154+
if pip install -e . ; then
155+
echo "INFO: Successfully installed baseline dependencies for ${PACKAGE_NAME}."
156+
python "${PROFILER_SCRIPT}" --package "${PACKAGE_NAME}" --iterations 11 --csv "${BASELINE_CSV}"
157+
if [ $? -eq 0 ]; then
158+
echo "INFO: Successfully ran baseline profiler for ${PACKAGE_NAME}."
159+
fi
160+
elif [[ "${PY_VERSION}" != "3.15"* ]]; then
161+
exit 1
162+
fi
129163
fi
130-
)
164+
); then
165+
git worktree remove -f "${WORKTREE_DIR}"
166+
deactivate
167+
rm -rf .venv-profiler
168+
rm -rf "${PROFILER_TEMP_DIR}"
169+
exit 1
170+
fi
131171
git worktree remove -f "${WORKTREE_DIR}"
132172
else
133173
echo "Failed to create git worktree for baseline. Skipping baseline generation."
@@ -137,14 +177,28 @@ case ${TEST_TYPE} in
137177
fi
138178
fi
139179

140-
pip install -e .
141-
142-
if [ -f "${BASELINE_CSV}" ]; then
143-
python ${PROFILER_SCRIPT} --package ${PACKAGE_NAME} --iterations 11 --fail-threshold 5000 --diff-baseline "${BASELINE_CSV}" --diff-threshold 100
180+
# TODO(https://github.com/googleapis/google-cloud-python/issues/18035):
181+
# Clean up this fallback once Python 3.15 is officially released and upstream binary wheels are available on PyPI.
182+
# On pre-release Python versions, packages with complex C/Rust dependencies (e.g. bigframes) fail during pip install due to missing pre-built wheels.
183+
if ! pip install -e . ; then
184+
if [[ "${PY_VERSION}" == "3.15"* ]]; then
185+
echo "WARNING: Could not install dependencies for ${PACKAGE_NAME} on Python ${PY_VERSION} (missing pre-built binary wheels for pre-release Python). Skipping import_profile."
186+
retval=0
187+
else
188+
retval=1
189+
fi
144190
else
145-
python ${PROFILER_SCRIPT} --package ${PACKAGE_NAME} --iterations 11 --fail-threshold 5000
191+
echo "INFO: Successfully installed dependencies for ${PACKAGE_NAME} on Python ${PY_VERSION}."
192+
if [ -f "${BASELINE_CSV}" ]; then
193+
python ${PROFILER_SCRIPT} --package ${PACKAGE_NAME} --iterations 11 --fail-threshold 5000 --diff-baseline "${BASELINE_CSV}" --diff-threshold 100
194+
else
195+
python ${PROFILER_SCRIPT} --package ${PACKAGE_NAME} --iterations 11 --fail-threshold 5000
196+
fi
197+
retval=$?
198+
if [ $retval -eq 0 ]; then
199+
echo "INFO: Successfully completed import_profile for ${PACKAGE_NAME}."
200+
fi
146201
fi
147-
retval=$?
148202
deactivate
149203
rm -rf .venv-profiler
150204
rm -rf "${PROFILER_TEMP_DIR}"

librarian.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414
language: python
15-
version: v0.31.0
15+
version: v0.35.0
1616
repo: googleapis/google-cloud-python
1717
sources:
1818
googleapis:

packages/bigframes/bigframes/display/table_widget_angular/package-lock.json

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)