Skip to content

Commit 181247a

Browse files
partheavchudnov-g
andauthored
feat: add Python 3.14 to samples testing image (#13596)
* feat: add Python 3.14 to samples testing image * address review feedback * formatting * wip * remove gpg;add sigstore;remove python 2.7 which doesn't support sigstore * fix typo * chore: add Py3.14 to noxfile-template --------- Co-authored-by: Victor Chudnovsky <vchudnov@google.com>
1 parent 04df049 commit 181247a

File tree

10 files changed

+195
-87
lines changed

10 files changed

+195
-87
lines changed

.kokoro/docker/Dockerfile

Lines changed: 63 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -110,33 +110,68 @@ RUN curl https://packages.microsoft.com/keys/microsoft.asc | apt-key add - \
110110
&& rm -rf /var/lib/apt/lists/* \
111111
&& rm -f /var/cache/apt/archives/*.deb
112112

113-
COPY fetch_gpg_keys.sh /tmp
114-
# Install the desired versions of Python.
115-
RUN set -ex \
116-
&& export GNUPGHOME="$(mktemp -d)" \
117-
&& echo "disable-ipv6" >> "${GNUPGHOME}/dirmngr.conf" \
118-
&& /tmp/fetch_gpg_keys.sh \
119-
&& for PYTHON_VERSION in 2.7.18 3.7.17 3.8.20 3.9.20 3.10.15 3.11.10 3.12.7 3.13.0; do \
120-
wget --no-check-certificate -O python-${PYTHON_VERSION}.tar.xz "https://www.python.org/ftp/python/${PYTHON_VERSION%%[a-z]*}/Python-$PYTHON_VERSION.tar.xz" \
121-
&& wget --no-check-certificate -O python-${PYTHON_VERSION}.tar.xz.asc "https://www.python.org/ftp/python/${PYTHON_VERSION%%[a-z]*}/Python-$PYTHON_VERSION.tar.xz.asc" \
122-
&& gpg --batch --verify python-${PYTHON_VERSION}.tar.xz.asc python-${PYTHON_VERSION}.tar.xz \
123-
&& rm -r python-${PYTHON_VERSION}.tar.xz.asc \
124-
&& mkdir -p /usr/src/python-${PYTHON_VERSION} \
125-
&& tar -xJC /usr/src/python-${PYTHON_VERSION} --strip-components=1 -f python-${PYTHON_VERSION}.tar.xz \
126-
&& rm python-${PYTHON_VERSION}.tar.xz \
127-
&& cd /usr/src/python-${PYTHON_VERSION} \
128-
&& ./configure \
129-
--enable-shared \
130-
# This works only on Python 2.7 and throws a warning on every other
131-
# version, but seems otherwise harmless.
132-
--enable-unicode=ucs4 \
133-
--with-system-ffi \
134-
--without-ensurepip \
135-
&& make -j$(nproc) \
136-
&& make install \
137-
&& ldconfig \
113+
# From https://www.python.org/downloads/metadata/sigstore/
114+
# Starting with Python 3.14, Sigstore is the only method of signing and verification of release artifacts.
115+
RUN LATEST_VERSION="2.6.1" && \
116+
wget "https://github.com/sigstore/cosign/releases/download/v${LATEST_VERSION}/cosign_${LATEST_VERSION}_amd64.deb" && \
117+
dpkg -i cosign_${LATEST_VERSION}_amd64.deb && \
118+
rm cosign_${LATEST_VERSION}_amd64.deb
119+
120+
ARG PYTHON_VERSIONS="3.7.17 3.8.20 3.9.23 3.10.18 3.11.13 3.12.11 3.13.8 3.14.0"
121+
122+
SHELL ["/bin/bash", "-c"]
123+
124+
RUN set -eux; \
125+
# Define the required associative arrays completely.
126+
declare -A PYTHON_IDENTITIES; \
127+
PYTHON_IDENTITIES=(\
128+
[3.7]="nad@python.org" \
129+
[3.8]="lukasz@langa.pl" \
130+
[3.9]="lukasz@langa.pl" \
131+
[3.10]="pablogsal@python.org" \
132+
[3.11]="pablogsal@python.org" \
133+
[3.12]="thomas@python.org" \
134+
[3.13]="thomas@python.org" \
135+
[3.14]="hugo@python.org" \
136+
); \
137+
declare -A PYTHON_ISSUERS; \
138+
PYTHON_ISSUERS=(\
139+
[3.7]="https://github.com/login/oauth" \
140+
[3.8]="https://github.com/login/oauth" \
141+
[3.9]="https://github.com/login/oauth" \
142+
[3.10]="https://accounts.google.com" \
143+
[3.11]="https://accounts.google.com" \
144+
[3.12]="https://accounts.google.com" \
145+
[3.13]="https://accounts.google.com" \
146+
[3.14]="https://github.com/login/oauth" \
147+
); \
148+
\
149+
for VERSION in $PYTHON_VERSIONS; do \
150+
# 1. Define VERSION_GROUP (e.g., 3.14 from 3.14.0)
151+
VERSION_GROUP="$(echo "${VERSION}" | cut -d . -f 1,2)"; \
152+
\
153+
# 2. Look up IDENTITY and ISSUER using the defined VERSION_GROUP
154+
IDENTITY="${PYTHON_IDENTITIES[$VERSION_GROUP]}"; \
155+
ISSUER="${PYTHON_ISSUERS[$VERSION_GROUP]}"; \
156+
\
157+
wget --quiet -O python-${VERSION}.tar.xz "https://www.python.org/ftp/python/${VERSION}/Python-$VERSION.tar.xz" \
158+
&& wget --quiet -O python-${VERSION}.tar.xz.sigstore "https://www.python.org/ftp/python/${VERSION}/Python-$VERSION.tar.xz.sigstore" \
159+
# Verify the Python tarball signature with cosign.
160+
&& cosign verify-blob python-${VERSION}.tar.xz \
161+
--certificate-oidc-issuer "${ISSUER}" \
162+
--certificate-identity "${IDENTITY}" \
163+
--bundle python-${VERSION}.tar.xz.sigstore \
164+
&& mkdir -p /usr/src/python-${VERSION} \
165+
&& tar -xJC /usr/src/python-${VERSION} --strip-components=1 -f python-${VERSION}.tar.xz \
166+
&& rm python-${VERSION}.tar.xz \
167+
&& cd /usr/src/python-${VERSION} \
168+
&& ./configure \
169+
--enable-shared \
170+
--with-system-ffi \
171+
&& make -j$(nproc) \
172+
&& make install \
173+
&& ldconfig \
138174
; done \
139-
&& rm -rf "${GNUPGHOME}" \
140175
&& rm -rf /usr/src/python* \
141176
&& rm -rf ~/.cache/
142177

@@ -158,6 +193,7 @@ RUN wget --no-check-certificate -O /tmp/get-pip-3-7.py 'https://bootstrap.pypa.i
158193
&& [ "$(pip list |tac|tac| awk -F '[ ()]+' '$1 == "pip" { print $2; exit }')" = "$PYTHON_PIP_VERSION" ]
159194

160195
# Ensure Pip for all python3 versions
196+
RUN python3.14 /tmp/get-pip.py
161197
RUN python3.13 /tmp/get-pip.py
162198
RUN python3.12 /tmp/get-pip.py
163199
RUN python3.11 /tmp/get-pip.py
@@ -175,6 +211,7 @@ RUN python3.10 -m pip
175211
RUN python3.11 -m pip
176212
RUN python3.12 -m pip
177213
RUN python3.13 -m pip
214+
RUN python3.14 -m pip
178215

179216
# Install "setuptools" for Python 3.12+ (see https://docs.python.org/3/whatsnew/3.12.html#distutils)
180217
RUN python3.12 -m pip install --no-cache-dir setuptools

.kokoro/docker/fetch_gpg_keys.sh

Lines changed: 0 additions & 57 deletions
This file was deleted.

.kokoro/python3.14/common.cfg

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
# Copyright 2025 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
# Format: //devtools/kokoro/config/proto/build.proto
16+
17+
timeout_mins: 300
18+
19+
# Configure the docker image for kokoro-trampoline.
20+
env_vars: {
21+
key: "TRAMPOLINE_IMAGE"
22+
value: "gcr.io/cloud-devrel-kokoro-resources/python-samples-testing-docker"
23+
}
24+
25+
# Download trampoline resources.
26+
gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/trampoline"
27+
28+
# Use the trampoline script to run in docker.
29+
build_file: "python-docs-samples/.kokoro/trampoline_v2.sh"
30+
31+
# Download secrets from Cloud Storage.
32+
gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/python-docs-samples"
33+
34+
# Access btlr binaries used in the tests
35+
gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/btlr"
36+
37+
# Copy results for Resultstore
38+
action {
39+
define_artifacts {
40+
regex: "**/*sponge_log.xml"
41+
}
42+
}
43+
44+
# Specify which tests to run
45+
env_vars: {
46+
key: "RUN_TESTS_SESSION"
47+
value: "py-3.14"
48+
}
49+
50+
env_vars: {
51+
key: "BUILD_SPECIFIC_GCLOUD_PROJECT"
52+
value: "python-docs-samples-tests-314"
53+
}
54+
55+
# Number of test workers.
56+
env_vars: {
57+
key: "NUM_TEST_WORKERS"
58+
value: "10"
59+
}

.kokoro/python3.14/continuous.cfg

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# Copyright 2025 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
# Format: //devtools/kokoro/config/proto/build.proto
16+
17+
# Tell the trampoline which build file to use.
18+
env_vars: {
19+
key: "TRAMPOLINE_BUILD_FILE"
20+
value: ".kokoro/tests/run_tests_diff_head.sh"
21+
}

.kokoro/python3.14/periodic.cfg

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# Copyright 2025 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
# Format: //devtools/kokoro/config/proto/build.proto
16+
17+
# Tell the trampoline which build file to use.
18+
env_vars: {
19+
key: "TRAMPOLINE_BUILD_FILE"
20+
value: ".kokoro/tests/run_tests.sh"
21+
}
22+
23+
# Tell Trampoline to upload the Docker image after successfull build.
24+
env_vars: {
25+
key: "TRAMPOLINE_IMAGE_UPLOAD"
26+
value: "true"
27+
}

.kokoro/python3.14/presubmit.cfg

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# Copyright 2025 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
# Format: //devtools/kokoro/config/proto/build.proto
16+
17+
# Tell the trampoline which build file to use.
18+
env_vars: {
19+
key: "TRAMPOLINE_BUILD_FILE"
20+
value: ".kokoro/tests/run_tests_diff_main.sh"
21+
}

.kokoro/tests/run_tests.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ if [[ $* == *--only-diff-head* ]]; then
5858
fi
5959
fi
6060

61-
# Because Kokoro runs presubmit builds simalteneously, we often see
61+
# Because Kokoro runs presubmit builds simultaneously, we often see
6262
# quota related errors. I think we can avoid this by changing the
6363
# order of tests to execute (e.g. reverse order for py-3.8
6464
# build). Currently there's no easy way to do that with btlr, so we

appengine/standard/noxfile-template.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ def get_pytest_env_vars():
7979

8080
# DO NOT EDIT - automatically generated.
8181
# All versions used to tested samples.
82-
ALL_VERSIONS = ["2.7", "3.6", "3.7", "3.8", "3.9", "3.10", "3.11", "3.12", "3.13"]
82+
ALL_VERSIONS = ["2.7", "3.6", "3.7", "3.8", "3.9", "3.10", "3.11", "3.12", "3.13", "3.14"]
8383

8484
# Any default versions that should be ignored.
8585
IGNORED_VERSIONS = ["3.6", "3.7", "3.8", "3.9", "3.10", "3.11", "3.12", "3.13"]

appengine/standard/noxfile_config.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424

2525
TEST_CONFIG_OVERRIDE = {
2626
# You can opt out from the test for specific Python versions.
27-
"ignored_versions": ["3.6", "3.7", "3.8", "3.9", "3.10", "3.11"],
27+
"ignored_versions": ["3.6", "3.7", "3.8", "3.10", "3.11", "3.12", "3.13"],
2828
# Old samples are opted out of enforcing Python type hints
2929
# All new samples should feature them
3030
"enforce_type_hints": False,

noxfile-template.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ def get_pytest_env_vars() -> dict[str, str]:
8888

8989

9090
# All versions used to tested samples.
91-
ALL_VERSIONS = ["2.7", "3.8", "3.9", "3.10", "3.11", "3.12", "3.13"]
91+
ALL_VERSIONS = ["2.7", "3.8", "3.9", "3.10", "3.11", "3.12", "3.13", "3.14"]
9292

9393
# Any default versions that should be ignored.
9494
IGNORED_VERSIONS = TEST_CONFIG["ignored_versions"]

0 commit comments

Comments
 (0)