diff --git a/.gitignore b/.gitignore index 496d51b39f..a09403b8a1 100644 --- a/.gitignore +++ b/.gitignore @@ -290,4 +290,4 @@ src/startupscriptgenerator/**/vendor/ src/startupscriptgenerator/src/**/__debug_bin src/startupscriptgenerator/src/**/run.sh !**/dynamic/Dockerfile -!**/dynamic/buster.Dockerfile \ No newline at end of file +!**/dynamic/buster.Dockerfile diff --git a/build/__pythonVersions.sh b/build/__pythonVersions.sh index 2c09969b9f..97118f4193 100755 --- a/build/__pythonVersions.sh +++ b/build/__pythonVersions.sh @@ -9,3 +9,4 @@ PYTHON38_VERSION='3.8.18' PYTHON39_VERSION='3.9.18' PYTHON310_VERSION='3.10.13' PYTHON311_VERSION='3.11.6' +PYTHON312_VERSION='3.12.0' diff --git a/build/buildPythonSdkByVersion.sh b/build/buildPythonSdkByVersion.sh index c74597d88a..bc444c90e1 100644 --- a/build/buildPythonSdkByVersion.sh +++ b/build/buildPythonSdkByVersion.sh @@ -165,12 +165,12 @@ getPythonGpgByVersion() { echo # TODO: Determine if we need to continue building newer versions of Python from scratch -echo "Building python 3.12 or newer from source code..." +echo "Building python 3.13 or newer from source code..." getPythonGpgByVersion "/tmp/versionsToBuild.txt" $version IFS='.' read -ra SPLIT_VERSION <<< "$PYTHON_VERSION" -if [ "${SPLIT_VERSION[0]}" == "3" ] && [ "${SPLIT_VERSION[1]}" -ge "12" ] +if [ "${SPLIT_VERSION[0]}" == "3" ] && [ "${SPLIT_VERSION[1]}" -ge "13" ] then buildPythonfromSource $version $pythonVersionGPG else diff --git a/build/buildRunTimeImages.sh b/build/buildRunTimeImages.sh index fff90083c3..e3437186b1 100755 --- a/build/buildRunTimeImages.sh +++ b/build/buildRunTimeImages.sh @@ -108,6 +108,9 @@ function getRuntimeTagVersion() elif [ "$PLATFORM_NAME" == "python" ] then case $PLATFORM_VERSION in + 3.12) + FULL_RUNTIME_TAG_VERSION=$PYTHON312_VERSION + ;; 3.11) FULL_RUNTIME_TAG_VERSION=$PYTHON311_VERSION ;; diff --git a/build/constants.yaml b/build/constants.yaml index b9d4fea278..1f57bd79f8 100644 --- a/build/constants.yaml +++ b/build/constants.yaml @@ -158,6 +158,7 @@ python39-version: 3.9.18 python310-version: 3.10.13 python311-version: 3.11.6 + python312-version: 3.12.0 runtime-versions: - 3.7-debian-bullseye - 3.7-debian-buster @@ -168,6 +169,7 @@ - 3.10-debian-bullseye - 3.10-debian-buster - 3.11-debian-bullseye + - 3.12-debian-bullseye - dynamic-debian-buster outputs: - type: csharp diff --git a/build/tools/Automation/Python/PythonConstants.cs b/build/tools/Automation/Python/PythonConstants.cs index 0a47e49faf..ca49d271ec 100644 --- a/build/tools/Automation/Python/PythonConstants.cs +++ b/build/tools/Automation/Python/PythonConstants.cs @@ -24,6 +24,7 @@ public class PythonConstants { "3.9", "E3FF2839C048B25C084DEBE9B26995E310250568" }, { "3.10", "A035C8C19219BA821ECEA86B64E628F8D684696D" }, { "3.11", "A035C8C19219BA821ECEA86B64E628F8D684696D" }, + { "3.12", "7169605F62C751356D054A26A821E680E5FA6305" }, }; } } diff --git a/doc/supportedPlatformVersions.md b/doc/supportedPlatformVersions.md index 8e6538ad98..6f3ced89d3 100644 --- a/doc/supportedPlatformVersions.md +++ b/doc/supportedPlatformVersions.md @@ -1219,6 +1219,7 @@ - 3.11.0b1 - 3.11.0 - 3.11.6 +- 3.12.0 ### buster diff --git a/doc/supportedRuntimeVersions.md b/doc/supportedRuntimeVersions.md index de230edb80..4fba25013d 100644 --- a/doc/supportedRuntimeVersions.md +++ b/doc/supportedRuntimeVersions.md @@ -87,6 +87,7 @@ The following are supported runtime versions for the image `mcr.microsoft.com/or - `3.9` - `3.10` - `3.11` +- `3.12` ## Ruby diff --git a/images/build/Dockerfiles/gitHubActions.Dockerfile b/images/build/Dockerfiles/gitHubActions.Dockerfile index f1ec003057..7634da09c7 100644 --- a/images/build/Dockerfiles/gitHubActions.Dockerfile +++ b/images/build/Dockerfiles/gitHubActions.Dockerfile @@ -75,6 +75,13 @@ RUN if [ "${DEBIAN_FLAVOR}" = "bookworm" ]; then \ libssl1.1 \ libyaml-dev \ libxml2 \ + # Adding lxml depended packages to avoid build failures + # https://lxml.de/installation.html#requirements + libxml2-dev \ + libxslt-dev \ + python3-dev \ + python3-setuptools \ + python3-wheel \ && rm -rf /var/lib/apt/lists/* ; \ elif [ "${DEBIAN_FLAVOR}" = "buster" ]; then \ apt-get update \ diff --git a/images/runtime/python/3.12/base.bullseye.Dockerfile b/images/runtime/python/3.12/base.bullseye.Dockerfile new file mode 100644 index 0000000000..f474447f64 --- /dev/null +++ b/images/runtime/python/3.12/base.bullseye.Dockerfile @@ -0,0 +1,91 @@ +ARG DEBIAN_FLAVOR +# Startup script generator +FROM mcr.microsoft.com/oss/go/microsoft/golang:1.18-${DEBIAN_FLAVOR} as startupCmdGen +# GOPATH is set to "/go" in the base image +WORKDIR /go/src +COPY src/startupscriptgenerator/src . +ARG GIT_COMMIT=unspecified +ARG BUILD_NUMBER=unspecified +ARG RELEASE_TAG_NAME=unspecified +ENV RELEASE_TAG_NAME=${RELEASE_TAG_NAME} +ENV GIT_COMMIT=${GIT_COMMIT} +ENV BUILD_NUMBER=${BUILD_NUMBER} +RUN ./build.sh python /opt/startupcmdgen/startupcmdgen + +FROM oryxdevmcr.azurecr.io/private/oryx/oryx-run-base-${DEBIAN_FLAVOR} as main +ARG DEBIAN_FLAVOR +ARG IMAGES_DIR=/tmp/oryx/images +ARG BUILD_DIR=/tmp/oryx/build +ENV DEBIAN_FLAVOR=${DEBIAN_FLAVOR} + +RUN apt-get update \ + && apt-get upgrade -y \ + && apt-get install -y --no-install-recommends \ + xz-utils \ + && rm -rf /var/lib/apt/lists/* + +ADD images ${IMAGES_DIR} +ADD build ${BUILD_DIR} +RUN find ${IMAGES_DIR} -type f -iname "*.sh" -exec chmod +x {} \; +RUN find ${BUILD_DIR} -type f -iname "*.sh" -exec chmod +x {} \; + +ENV PYTHON_VERSION 3.12.0 +RUN true +COPY build/__pythonVersions.sh ${BUILD_DIR} +RUN true +COPY platforms/__common.sh /tmp/ +RUN true +COPY platforms/python/prereqs/build.sh /tmp/ +RUN true +COPY platforms/python/versions/${DEBIAN_FLAVOR}/versionsToBuild.txt /tmp/ +RUN true +COPY images/receiveGpgKeys.sh /tmp/receiveGpgKeys.sh +RUN true + +RUN chmod +x /tmp/receiveGpgKeys.sh +RUN chmod +x /tmp/build.sh && \ + apt-get update && \ + DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ + build-essential \ + tk-dev \ + uuid-dev \ + libgeos-dev + +RUN --mount=type=secret,id=oryx_sdk_storage_account_access_token \ + set -e \ + && export ORYX_SDK_STORAGE_ACCOUNT_ACCESS_TOKEN_PATH="/run/secrets/oryx_sdk_storage_account_access_token" \ + && ${BUILD_DIR}/buildPythonSdkByVersion.sh $PYTHON_VERSION + +RUN set -ex \ + && cd /opt/python/ \ + && ln -s 3.12.0 3.12 \ + && ln -s 3.12 3 \ + && echo /opt/python/3/lib >> /etc/ld.so.conf.d/python.conf \ + && ldconfig \ + && cd /opt/python/3/bin \ + && ln -nsf idle3 idle \ + && ln -nsf pydoc3 pydoc \ + && ln -nsf python3-config python-config \ + && rm -rf /var/lib/apt/lists/* + +ENV PATH="/opt/python/3/bin:${PATH}" + +# Bake Application Insights key from pipeline variable into final image +ARG AI_CONNECTION_STRING +ENV ORYX_AI_CONNECTION_STRING=${AI_CONNECTION_STRING} + +RUN ${IMAGES_DIR}/runtime/python/install-dependencies.sh + +RUN pip install --upgrade pip \ + && pip install gunicorn \ + && pip install debugpy \ + && pip install viztracer \ + && pip install vizplugins \ + && pip install orjson \ + && ln -s /opt/startupcmdgen/startupcmdgen /usr/local/bin/oryx \ + && apt-get update \ + && apt-get upgrade --assume-yes \ + && rm -rf /var/lib/apt/lists/* \ + && rm -rf /tmp/oryx + +COPY --from=startupCmdGen /opt/startupcmdgen/startupcmdgen /opt/startupcmdgen/startupcmdgen diff --git a/images/runtime/python/3.12/bullseye.Dockerfile b/images/runtime/python/3.12/bullseye.Dockerfile new file mode 100644 index 0000000000..66f6d9d432 --- /dev/null +++ b/images/runtime/python/3.12/bullseye.Dockerfile @@ -0,0 +1,104 @@ +ARG DEBIAN_FLAVOR +# Startup script generator +FROM mcr.microsoft.com/oss/go/microsoft/golang:1.19-${DEBIAN_FLAVOR} as startupCmdGen +# GOPATH is set to "/go" in the base image +WORKDIR /go/src +COPY src/startupscriptgenerator/src . +ARG GIT_COMMIT=unspecified +ARG BUILD_NUMBER=unspecified +ARG RELEASE_TAG_NAME=unspecified +ENV RELEASE_TAG_NAME=${RELEASE_TAG_NAME} +ENV GIT_COMMIT=${GIT_COMMIT} +ENV BUILD_NUMBER=${BUILD_NUMBER} +#Bake in client certificate path into image to avoid downloading it +ENV PATH_CA_CERTIFICATE="/etc/ssl/certs/ca-certificate.crt" +RUN ./build.sh python /opt/startupcmdgen/startupcmdgen + +FROM oryxdevmcr.azurecr.io/private/oryx/oryx-run-base-bullseye as main +ARG DEBIAN_FLAVOR +ARG IMAGES_DIR=/tmp/oryx/images +ARG BUILD_DIR=/tmp/oryx/build +ARG SDK_STORAGE_BASE_URL_VALUE +ENV DEBIAN_FLAVOR=${DEBIAN_FLAVOR} +ENV ORYX_SDK_STORAGE_BASE_URL=${SDK_STORAGE_BASE_URL_VALUE} + +RUN apt-get update \ + && apt-get upgrade -y \ + && apt-get install -y --no-install-recommends \ + xz-utils \ + # Install gcc due to error installing viztracer returning gcc not found + gcc \ + && rm -rf /var/lib/apt/lists/* + +ADD images ${IMAGES_DIR} +ADD build ${BUILD_DIR} +RUN find ${IMAGES_DIR} -type f -iname "*.sh" -exec chmod +x {} \; +RUN find ${BUILD_DIR} -type f -iname "*.sh" -exec chmod +x {} \; + +ENV PYTHON_VERSION 3.12.0 +RUN true +COPY build/__pythonVersions.sh ${BUILD_DIR} +RUN true +COPY platforms/__common.sh /tmp/ +RUN true +COPY platforms/python/prereqs/build.sh /tmp/ +RUN true +COPY platforms/python/versions/${DEBIAN_FLAVOR}/versionsToBuild.txt /tmp/ +RUN true +COPY images/receiveGpgKeys.sh /tmp/receiveGpgKeys.sh +RUN true + +RUN chmod +x /tmp/receiveGpgKeys.sh +RUN chmod +x /tmp/build.sh + +RUN --mount=type=secret,id=oryx_sdk_storage_account_access_token \ + set -e \ + && export ORYX_SDK_STORAGE_ACCOUNT_ACCESS_TOKEN_PATH="/run/secrets/oryx_sdk_storage_account_access_token" \ + && ${BUILD_DIR}/buildPythonSdkByVersion.sh $PYTHON_VERSION $DEBIAN_FLAVOR + +RUN set -ex \ + && cd /opt/python/ \ + && ln -s 3.12.0 3.12 \ + && ln -s 3.12 3 \ + && echo /opt/python/3/lib >> /etc/ld.so.conf.d/python.conf \ + && ldconfig \ + && if [ "3" = "3" ]; then cd /opt/python/3/bin \ + && ln -nsf idle3 idle \ + && ln -nsf pydoc3 pydoc \ + && ln -nsf python3-config python-config; fi \ + && rm -rf /var/lib/apt/lists/* + +ENV PATH="/opt/python/3/bin:${PATH}" + +# Bake Application Insights key from pipeline variable into final image +ARG AI_CONNECTION_STRING +ENV ORYX_AI_CONNECTION_STRING=${AI_CONNECTION_STRING} +#Bake in client certificate path into image to avoid downloading it +ENV PATH_CA_CERTIFICATE="/etc/ssl/certs/ca-certificate.crt" + +# Oryx++ Builder variables +ENV CNB_STACK_ID="oryx.stacks.skeleton" +LABEL io.buildpacks.stack.id="oryx.stacks.skeleton" + +RUN ${IMAGES_DIR}/runtime/python/install-dependencies.sh +RUN pip install --upgrade pip \ + && pip install gunicorn \ + && pip install debugpy \ + && pip install viztracer==0.15.6 \ + && pip install vizplugins==0.1.3 \ + # Removing orjson only for 3.12 due to build errors + && if [ "3.12" != "3.12" ]; then pip install orjson==3.8.10; fi \ + && if [ "3.12" = "3.7" ] || [ "3.12" = "3.8" ]; then curl -LO http://ftp.de.debian.org/debian/pool/main/libf/libffi/libffi6_3.2.1-9_amd64.deb \ + && dpkg -i libffi6_3.2.1-9_amd64.deb \ + && rm libffi6_3.2.1-9_amd64.deb; fi \ + && ln -s /opt/startupcmdgen/startupcmdgen /usr/local/bin/oryx \ + && apt-get update \ + && apt-get upgrade --assume-yes \ + && rm -rf /var/lib/apt/lists/* \ + && rm -rf /tmp/oryx + +ENV LANG="en_US.UTF-8" \ + LANGUAGE="en_US.UTF-8" \ + LC_ALL="en_US.UTF-8" + +COPY --from=startupCmdGen /opt/startupcmdgen/startupcmdgen /opt/startupcmdgen/startupcmdgen diff --git a/images/runtime/python/generateDockerfiles.sh b/images/runtime/python/generateDockerfiles.sh index 4f0e8dacf2..cab0ae87ce 100755 --- a/images/runtime/python/generateDockerfiles.sh +++ b/images/runtime/python/generateDockerfiles.sh @@ -23,7 +23,7 @@ source "$PYTHON_VERSIONS_PATH" # Please make sure that any changes to debian flavors supported here are also reflected in build/constants.yaml declare -r PYTHON_BOOKWORM_VERSION_ARRAY=() -declare -r PYTHON_BULLSEYE_VERSION_ARRAY=($PYTHON37_VERSION $PYTHON38_VERSION $PYTHON39_VERSION $PYTHON310_VERSION $PYTHON311_VERSION) +declare -r PYTHON_BULLSEYE_VERSION_ARRAY=($PYTHON37_VERSION $PYTHON38_VERSION $PYTHON39_VERSION $PYTHON310_VERSION $PYTHON311_VERSION $PYTHON312_VERSION) declare -r PYTHON_BUSTER_VERSION_ARRAY=($PYTHON37_VERSION $PYTHON38_VERSION $PYTHON39_VERSION $PYTHON310_VERSION) ImageDebianFlavor="$1" echo "python baseimage type: $ImageDebianFlavor" diff --git a/images/runtime/python/template.Dockerfile b/images/runtime/python/template.Dockerfile index f716c19fd6..fd6d952dc9 100644 --- a/images/runtime/python/template.Dockerfile +++ b/images/runtime/python/template.Dockerfile @@ -26,6 +26,8 @@ RUN apt-get update \ && apt-get upgrade -y \ && apt-get install -y --no-install-recommends \ xz-utils \ + # Install gcc due to error installing viztracer returning gcc not found + gcc \ && rm -rf /var/lib/apt/lists/* ADD images ${IMAGES_DIR} @@ -84,7 +86,8 @@ RUN pip install --upgrade pip \ && pip install debugpy \ && pip install viztracer==0.15.6 \ && pip install vizplugins==0.1.3 \ - && pip install orjson==3.8.1 \ + # Removing orjson only for 3.12 due to build errors + && if [ "%PYTHON_VERSION%" != "3.12" ]; then pip install orjson==3.8.10; fi \ && if [ "%PYTHON_VERSION%" = "3.7" ] || [ "%PYTHON_VERSION%" = "3.8" ]; then curl -LO http://ftp.de.debian.org/debian/pool/main/libf/libffi/libffi6_3.2.1-9_amd64.deb \ && dpkg -i libffi6_3.2.1-9_amd64.deb \ && rm libffi6_3.2.1-9_amd64.deb; fi \ diff --git a/platforms/python/prereqs/build.sh b/platforms/python/prereqs/build.sh index 89bbd3a099..e49f4e7145 100755 --- a/platforms/python/prereqs/build.sh +++ b/platforms/python/prereqs/build.sh @@ -93,8 +93,12 @@ make -j $(nproc) make install -if [ "${PYTHON_VERSION[0]}" == "3" ] && [ "${PYTHON_VERSION[1]}" -ge "10" ] +# python3.12.0 version requires the updated pip version. The older pip version:21.2.4 does not work with python3.12.0. +IFS='.' read -ra SPLIT_VERSION <<< "$PYTHON_VERSION" +if [ "${SPLIT_VERSION[0]}" == "3" ] && [ "${SPLIT_VERSION[1]}" -ge "12" ] then + export LD_LIBRARY_PATH="/opt/python/$PYTHON_VERSION/lib/" + /opt/python/$PYTHON_VERSION/bin/python3 --version rm -rf /usr/src/python find /usr/local -depth \ \( \ @@ -103,31 +107,29 @@ then \) -exec rm -rf '{}' + \ ldconfig - python3 --version # make some useful symlinks that are expected to exist - cd /usr/local/bin + cd /opt/python/$PYTHON_VERSION/bin/ ln -s idle3 idle ln -s pydoc3 pydoc ln -s python3 python ln -s python3-config python-config - PYTHON_GET_PIP_SHA256="c518250e91a70d7b20cceb15272209a4ded2a0c263ae5776f129e0d9b5674309" # Install pip wget "$PYTHON_GET_PIP_URL" -O get-pip.py - python3 get-pip.py \ + /opt/python/$PYTHON_VERSION/bin/python3 get-pip.py \ --trusted-host pypi.python.org \ --trusted-host pypi.org \ --trusted-host files.pythonhosted.org \ --disable-pip-version-check \ --no-cache-dir \ --no-warn-script-location - rm -rf /configure* /config.* /*.txt /*.md /*.rst /*.toml /*.m4 /tmpFiles rm -rf /LICENSE /install-sh /Makefile* /pyconfig* /python.tar* /python-* /libpython3.* /setup.py rm -rf /Python /PCbuild /Grammar /python /Objects /Parser /Misc /Tools /Programs /Modules /Include /Mac /Doc /PC /Lib + else # Install pip wget "$PYTHON_GET_PIP_URL" -O get-pip.py @@ -170,7 +172,9 @@ echo # Replace log level in pip's code as a workaround for https://github.com/pypa/pip/issues/6189 pipReqSetPath=`find $INSTALLATION_PREFIX/lib -path "*site-packages/pip/_internal/req/req_set.py"` -sed -i 's|logger\.debug('\''Cleaning up\.\.\.'\'')|logger\.info('\''Cleaning up\.\.\.'\'')|' "$pipReqSetPath" +if [ -n "$pipReqSetPath" ]; then + sed -i 's|logger\.debug('\''Cleaning up\.\.\.'\'')|logger\.info('\''Cleaning up\.\.\.'\'')|' "$pipReqSetPath" +fi compressedSdkDir="/tmp/compressedSdk" mkdir -p $compressedSdkDir diff --git a/platforms/python/versions/bullseye/versionsToBuild.txt b/platforms/python/versions/bullseye/versionsToBuild.txt index 9f200a6d45..d4aa3cb2ab 100644 --- a/platforms/python/versions/bullseye/versionsToBuild.txt +++ b/platforms/python/versions/bullseye/versionsToBuild.txt @@ -1,14 +1,6 @@ # NOTE: Make sure to set the default version in 'defaultVersion.txt' file # version, gpg keys, dockerfile -3.10.0, A035C8C19219BA821ECEA86B64E628F8D684696D, -3.10.0a2, A035C8C19219BA821ECEA86B64E628F8D684696D, -3.10.13, A035C8C19219BA821ECEA86B64E628F8D684696D, -3.10.4, A035C8C19219BA821ECEA86B64E628F8D684696D, -3.10.8, A035C8C19219BA821ECEA86B64E628F8D684696D, -3.11.0, A035C8C19219BA821ECEA86B64E628F8D684696D -3.11.0b1, A035C8C19219BA821ECEA86B64E628F8D684696D, -3.11.6, A035C8C19219BA821ECEA86B64E628F8D684696D, 3.7.12, 0D96DF4D4110E5C43FBFB17F2D347EA6AA65421D, 3.7.15, 0D96DF4D4110E5C43FBFB17F2D347EA6AA65421D, 3.7.9, 0D96DF4D4110E5C43FBFB17F2D347EA6AA65421D, @@ -22,3 +14,15 @@ 3.9.18, E3FF2839C048B25C084DEBE9B26995E310250568, 3.9.1rc1, E3FF2839C048B25C084DEBE9B26995E310250568, 3.9.7, E3FF2839C048B25C084DEBE9B26995E310250568, +3.9.15, E3FF2839C048B25C084DEBE9B26995E310250568, +3.10.0, A035C8C19219BA821ECEA86B64E628F8D684696D, +3.10.0a2, A035C8C19219BA821ECEA86B64E628F8D684696D, +3.10.13, A035C8C19219BA821ECEA86B64E628F8D684696D, +3.10.4, A035C8C19219BA821ECEA86B64E628F8D684696D, +3.10.8, A035C8C19219BA821ECEA86B64E628F8D684696D, +3.11.0, A035C8C19219BA821ECEA86B64E628F8D684696D, +3.11.0b1, A035C8C19219BA821ECEA86B64E628F8D684696D, +3.11.6, A035C8C19219BA821ECEA86B64E628F8D684696D, +3.12.0, 7169605F62C751356D054A26A821E680E5FA6305, + +# NOTE: Make sure to set the default version in 'defaultVersion.txt' file diff --git a/src/BuildScriptGenerator/PythonVersions.cs b/src/BuildScriptGenerator/PythonVersions.cs index 7ee9764fb6..72c01d7e82 100644 --- a/src/BuildScriptGenerator/PythonVersions.cs +++ b/src/BuildScriptGenerator/PythonVersions.cs @@ -15,6 +15,7 @@ public static class PythonVersions public const string Python39Version = "3.9.18"; public const string Python310Version = "3.10.13"; public const string Python311Version = "3.11.6"; - public static readonly List RuntimeVersions = new List { "3.7-debian-bullseye", "3.7-debian-buster", "3.8-debian-bullseye", "3.8-debian-buster", "3.9-debian-bullseye", "3.9-debian-buster", "3.10-debian-bullseye", "3.10-debian-buster", "3.11-debian-bullseye", "dynamic-debian-buster" }; + public const string Python312Version = "3.12.0"; + public static readonly List RuntimeVersions = new List { "3.7-debian-bullseye", "3.7-debian-buster", "3.8-debian-bullseye", "3.8-debian-buster", "3.9-debian-bullseye", "3.9-debian-buster", "3.10-debian-bullseye", "3.10-debian-buster", "3.11-debian-bullseye", "3.12-debian-bullseye", "dynamic-debian-buster" }; } } \ No newline at end of file diff --git a/tests/BuildScriptGenerator.Tests/DefaultDockerfileGeneratorTest.cs b/tests/BuildScriptGenerator.Tests/DefaultDockerfileGeneratorTest.cs index e364d5f9f6..68be1db5e0 100644 --- a/tests/BuildScriptGenerator.Tests/DefaultDockerfileGeneratorTest.cs +++ b/tests/BuildScriptGenerator.Tests/DefaultDockerfileGeneratorTest.cs @@ -127,6 +127,7 @@ public void GenerateDockerfile_GeneratesBuildTagAndRuntime_ForProvidedPlatformAn [InlineData("python", "3.9", "debian-bullseye-stable", "3.9-debian-bullseye")] [InlineData("python", "3.10", "debian-bullseye-stable", "3.10-debian-bullseye")] [InlineData("python", "3.11", "debian-bullseye-stable", "3.11-debian-bullseye")] + [InlineData("python", "3.12", "debian-bullseye-stable", "3.12-debian-bullseye")] [InlineData("python", "3.6", "debian-buster-stable", "dynamic-debian-buster")] // 3.6.x not currently a runtime, use dynamic [InlineData("python", "3.8.1", "debian-bullseye-stable", "3.8-debian-bullseye")] public void GenerateDockerfile_GeneratesBuildTagAndRuntime_ForProvidedPlatform( @@ -188,6 +189,7 @@ public void GenerateDockerfile_GeneratesBuildTagAndRuntime_ForProvidedPlatform( [InlineData("python", "3.9", "debian-bullseye-stable", "3.9-debian-bullseye")] [InlineData("python", "3.10", "debian-bullseye-stable", "3.10-debian-bullseye")] [InlineData("python", "3.11", "debian-bullseye-stable", "3.11-debian-bullseye")] + [InlineData("python", "3.12", "debian-bullseye-stable", "3.12-debian-bullseye")] [InlineData("python", "3.6", "debian-buster-stable", "dynamic-debian-buster")] // 3.6.x not currently a runtime, use dynamic [InlineData("python", "3.8.1", "debian-bullseye-stable", "3.8-debian-bullseye")] public void GenerateDockerfile_GeneratesBuildTagAndRuntime_ForNoProvidedPlatform( diff --git a/tests/Oryx.BuildImage.Tests/Python/PythonDynamicInstallationTest.cs b/tests/Oryx.BuildImage.Tests/Python/PythonDynamicInstallationTest.cs index 7d5d180476..2c0b18fbcd 100644 --- a/tests/Oryx.BuildImage.Tests/Python/PythonDynamicInstallationTest.cs +++ b/tests/Oryx.BuildImage.Tests/Python/PythonDynamicInstallationTest.cs @@ -40,6 +40,7 @@ public void PipelineTestInvocationGithubActions() GeneratesScript_AndBuildsPython_FlaskApp(imageTestHelper.GetGitHubActionsBuildImage(ImageTestHelperConstants.GitHubActionsBuster), PythonVersions.Python39Version); GeneratesScript_AndBuildsPython_FlaskApp(imageTestHelper.GetGitHubActionsBuildImage(ImageTestHelperConstants.GitHubActionsBullseye), PythonVersions.Python310Version); GeneratesScript_AndBuildsPython_FlaskApp(imageTestHelper.GetGitHubActionsBuildImage(ImageTestHelperConstants.GitHubActionsBullseye), PythonVersions.Python311Version); + GeneratesScript_AndBuildsPython_FlaskApp(imageTestHelper.GetGitHubActionsBuildImage(ImageTestHelperConstants.GitHubActionsBullseye), PythonVersions.Python312Version); GeneratesScript_AndBuildsPython_PyodbcApp(imageTestHelper.GetGitHubActionsBuildImage(ImageTestHelperConstants.GitHubActionsBullseye), PythonVersions.Python37Version); GeneratesScript_AndBuildsPython_PyodbcApp(imageTestHelper.GetGitHubActionsBuildImage(ImageTestHelperConstants.GitHubActionsBullseye), PythonVersions.Python38Version); @@ -50,6 +51,7 @@ public void PipelineTestInvocationGithubActions() GeneratesScript_AndBuildsPython_DjangoRegexApp(imageTestHelper.GetGitHubActionsBuildImage(ImageTestHelperConstants.GitHubActionsBullseye), PythonVersions.Python310Version); GeneratesScript_AndBuildsPython_DjangoRegexApp(imageTestHelper.GetGitHubActionsBuildImage(ImageTestHelperConstants.GitHubActionsBullseye), PythonVersions.Python311Version); + GeneratesScript_AndBuildsPython_DjangoRegexApp(imageTestHelper.GetGitHubActionsBuildImage(ImageTestHelperConstants.GitHubActionsBullseye), PythonVersions.Python312Version); } [Fact, Trait("category", "cli-stretch")] @@ -213,6 +215,7 @@ private void GeneratesScript_AndBuildsPython_PyodbcApp( [Theory, Trait("category", "jamstack")] [InlineData(PythonVersions.Python310Version)] [InlineData(PythonVersions.Python311Version)] + [InlineData(PythonVersions.Python312Version)] public void GeneratesScript_AndBuildsPython_JamstackBuildImage(string version) { // Arrange @@ -474,6 +477,7 @@ public static TheoryData SupportedVersionAndImageNameData data.Add(PythonVersions.Python39Version, imageHelper.GetAzureFunctionsJamStackBuildImage(ImageTestHelperConstants.AzureFunctionsJamStackBullseye)); data.Add(PythonVersions.Python310Version, imageHelper.GetAzureFunctionsJamStackBuildImage(ImageTestHelperConstants.AzureFunctionsJamStackBullseye)); data.Add(PythonVersions.Python311Version, imageHelper.GetAzureFunctionsJamStackBuildImage(ImageTestHelperConstants.AzureFunctionsJamStackBullseye)); + data.Add(PythonVersions.Python312Version, imageHelper.GetAzureFunctionsJamStackBuildImage(ImageTestHelperConstants.AzureFunctionsJamStackBullseye)); return data; } } diff --git a/tests/Oryx.Integration.Tests/Python/PythonEndToEndTests.cs b/tests/Oryx.Integration.Tests/Python/PythonEndToEndTests.cs index 0c31d55233..3adfd51542 100644 --- a/tests/Oryx.Integration.Tests/Python/PythonEndToEndTests.cs +++ b/tests/Oryx.Integration.Tests/Python/PythonEndToEndTests.cs @@ -116,6 +116,54 @@ await EndToEndTestHelper.BuildRunAndAssertAppAsync( }); } + [Fact] + [Trait("category", "python-3.12")] + [Trait("build-image", "github-actions-debian-bullseye")] + public async Task CanBuildAndRun_DjangoRegex_Python12() + { + // Arrange + var version = "3.12"; + var osType = ImageTestHelperConstants.OsTypeDebianBullseye; + var appName = "django-regex-example-app"; + var volume = CreateAppVolume(appName); + var appDir = volume.ContainerDir; + var appOutputDirVolume = CreateAppOutputDirVolume(); + var appOutputDir = appOutputDirVolume.ContainerDir; + var buildScript = new ShellScriptBuilder() + .AddCommand($"oryx build {appDir} -i /tmp/int -o {appOutputDir} " + + $"--platform {PythonConstants.PlatformName} --platform-version {PythonVersions.Python312Version}") + .ToString(); + var runScript = new ShellScriptBuilder() + .AddCommand($"oryx create-script -appPath {appOutputDir} -bindPort {ContainerPort}") + .AddCommand(DefaultStartupFilePath) + .ToString(); + + await EndToEndTestHelper.BuildRunAndAssertAppAsync( + appName, + _output, + new[] { volume, appOutputDirVolume }, + _imageHelper.GetGitHubActionsBuildImage(ImageTestHelperConstants.GitHubActionsBullseye), + "/bin/bash", + new[] + { + "-c", + buildScript + }, + _imageHelper.GetRuntimeImage("python", version, osType), + ContainerPort, + "/bin/bash", + new[] + { + "-c", + runScript + }, + async (hostPort) => + { + var data = await _httpClient.GetStringAsync($"http://localhost:{hostPort}/"); + Assert.Contains("Hello world from Django!", data); + }); + } + [Theory] [Trait("category", "python-3.7")] [Trait("build-image", "debian-stretch")] diff --git a/tests/Oryx.RuntimeImage.Tests/Python/PythonImagesTests.cs b/tests/Oryx.RuntimeImage.Tests/Python/PythonImagesTests.cs index 93fccd3c7b..e1bb150963 100644 --- a/tests/Oryx.RuntimeImage.Tests/Python/PythonImagesTests.cs +++ b/tests/Oryx.RuntimeImage.Tests/Python/PythonImagesTests.cs @@ -165,6 +165,7 @@ public void JamSpell_CanBe_InstalledInBullseyeRunTimeImage(string version) [InlineData("3.9", "Python " + PythonVersions.Python39Version)] [InlineData("3.10", "Python " + PythonVersions.Python310Version)] [InlineData("3.11", "Python " + PythonVersions.Python311Version)] + [InlineData("3.12", "Python " + PythonVersions.Python312Version)] [Trait(TestConstants.Category, TestConstants.Release)] public void PythonVersionMatchesBullseyeImageName(string pythonVersion, string expectedOutput) { diff --git a/tests/SampleApps/python/django-app/requirements.txt b/tests/SampleApps/python/django-app/requirements.txt index 124b3824df..efd8786c12 100644 --- a/tests/SampleApps/python/django-app/requirements.txt +++ b/tests/SampleApps/python/django-app/requirements.txt @@ -1,3 +1,4 @@ Django==2.2.28 pytz==2018.7 +django-utils-six==2.0 whitenoise==4.1.1 \ No newline at end of file diff --git a/tests/SampleApps/python/django-regex-example-app/requirements.txt b/tests/SampleApps/python/django-regex-example-app/requirements.txt index 313c695d6c..fe3801e92a 100644 --- a/tests/SampleApps/python/django-regex-example-app/requirements.txt +++ b/tests/SampleApps/python/django-regex-example-app/requirements.txt @@ -59,7 +59,7 @@ isodate==0.6.0 itertable==2.0.0 kombu==5.2.4 libsass==0.21.0 -lxml==4.9.1 +lxml==4.9.3 MarkupPy==1.14 msal==1.21.0 msal-extensions==0.3.0 @@ -81,7 +81,7 @@ pyparsing==3.0.9 python-dateutil==2.8.2 python3-openid==3.2.0 pytz==2022.5 -PyYAML==6.0 +PyYAML==6.0.1 qrcode==6.1 rcssmin==1.0.6 redis==4.4.4