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"
@@ -29,12 +30,13 @@ jobs:
2930 matrix : ${{ steps.set-matrix.outputs.matrix }}
3031 is_full_run : ${{ steps.check-label.outputs.is_full_run }}
3132 env :
32- MAX_SHARDS : 16
33+ MAX_SHARDS : 20
3334 # Define weights for long-running unit tests to balance shard execution time
3435 # Each weight is roughly 1 minute of expected execution time
3536 # Default for unset packages is 1
3637 PACKAGE_WEIGHTS : |
3738 bigframes: 6
39+ sqlalchemy-spanner: 6
3840 google-ai-generativelanguage: 4
3941 google-auth: 5
4042 google-cloud-compute: 12
8183 if : needs.initialize.outputs.matrix != '[]' && needs.initialize.outputs.matrix != ''
8284 runs-on : ubuntu-22.04
8385 strategy :
84- 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
0 commit comments