diff --git a/.github/workflows/build_python_runtime.yml b/.github/workflows/build_python_runtime.yml index 9b90fc052..3e8d5dc73 100644 --- a/.github/workflows/build_python_runtime.yml +++ b/.github/workflows/build_python_runtime.yml @@ -58,8 +58,7 @@ jobs: run: aws s3 sync ./upload "s3://${S3_BUCKET}" heroku-22: - # On Heroku-22 we only support Python 3.9+. - if: inputs.stack == 'heroku-22' || (inputs.stack == 'auto' && !startsWith(inputs.python_version,'3.8.')) + if: inputs.stack == 'heroku-22' || inputs.stack == 'auto' runs-on: pub-hk-ubuntu-24.04-xlarge env: STACK_VERSION: "22" @@ -80,8 +79,7 @@ jobs: run: aws s3 sync ./upload "s3://${S3_BUCKET}" heroku-24: - # On Heroku-24 we only support Python 3.9+. - if: inputs.stack == 'heroku-24' || (inputs.stack == 'auto' && !startsWith(inputs.python_version,'3.8.')) + if: inputs.stack == 'heroku-24' || inputs.stack == 'auto' strategy: fail-fast: false matrix: diff --git a/CHANGELOG.md b/CHANGELOG.md index 76c5e5834..0c5e5c2f9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,9 @@ ## [Unreleased] +- Added a deprecation warning for Python 3.9. ([#1732](https://github.com/heroku/heroku-buildpack-python/pull/1732)) +- Removed support for Python 3.8. ([#1732](https://github.com/heroku/heroku-buildpack-python/pull/1732)) +- Improved the error messages shown for EOL or unrecognised major Python versions. ([#1732](https://github.com/heroku/heroku-buildpack-python/pull/1732)) ## [v273] - 2025-01-03 diff --git a/README.md b/README.md index 34684120f..3c76ddc14 100644 --- a/README.md +++ b/README.md @@ -49,7 +49,6 @@ The supported Python versions are: These Python versions are deprecated on Heroku: - Python 3.9 -- Python 3.8 (only available on the [Heroku-20](https://devcenter.heroku.com/articles/heroku-20-stack) stack) Python versions older than those listed above are no longer supported, since they have reached end-of-life [upstream](https://devguide.python.org/versions/#supported-versions). diff --git a/bin/compile b/bin/compile index 7edf8a44c..08232b5e7 100755 --- a/bin/compile +++ b/bin/compile @@ -194,7 +194,7 @@ meta_time "package_manager_install_duration" "${package_manager_install_start_ti # Installs the sqlite3 dev headers and sqlite3 binary but not the # libsqlite3-0 library since that exists in the base image. # We skip this step on Python 3.13 or when using Poetry, as a first step towards removing this feature. -if [[ "${python_major_version}" == +(3.8|3.9|3.10|3.11|3.12) && "${package_manager}" != "poetry" ]]; then +if [[ "${python_major_version}" == +(3.9|3.10|3.11|3.12) && "${package_manager}" != "poetry" ]]; then install_sqlite_start_time=$(nowms) source "${BUILDPACK_DIR}/bin/steps/sqlite3" buildpack_sqlite3_install diff --git a/bin/steps/python b/bin/steps/python index 797bc038d..b345d5cd8 100755 --- a/bin/steps/python +++ b/bin/steps/python @@ -14,7 +14,7 @@ PYTHON_URL="${S3_BASE_URL}/python-${python_full_version}-ubuntu-${UBUNTU_VERSION # 1. It's a Python major version we've deprecated and so is only available on older stacks (i.e: Python 3.8). # 2. If an exact Python version was requested and the patch version doesn't exist (e.g. 3.12.999). # 3. The user has pinned to an older buildpack version and the S3 bucket location or layout has changed since. -# TODO: Update this message to be more specific once Python 3.8 support is dropped. +# TODO: Update this message to be more specific now that Python 3.8 support has been removed, and so (1) can no longer occur. if ! curl --output /dev/null --silent --head --fail --retry 3 --retry-connrefused --connect-timeout 10 "${PYTHON_URL}"; then output::error <<-EOF Error: Python ${python_full_version} isn't available for this stack (${STACK}). @@ -74,18 +74,22 @@ function warn_if_patch_update_available() { # We wait until now to display outdated Python version warnings, since we only want to show them # if there weren't any errors with the version to avoid adding noise to the error messages. # TODO: Move this into lib/ as part of the warnings refactor. -if [[ "${python_major_version}" == "3.8" ]]; then - output::warning <<-'EOF' - Warning: Support for Python 3.8 is ending soon! +if [[ "${python_major_version}" == "3.9" ]]; then + output::warning <<-EOF + Warning: Support for Python 3.9 is ending soon! - Python 3.8 reached its upstream end-of-life on 7th October 2024, and so - no longer receives security updates: + Python 3.9 will reach its upstream end-of-life in October 2025, + at which point it will no longer receive security updates: https://devguide.python.org/versions/#supported-versions - Support for Python 3.8 will be removed from this buildpack on 7th January 2025. + As such, support for Python 3.9 will be removed from this + buildpack on 7th January 2026. - Upgrade to a newer Python version as soon as possible to keep your app secure. - See: https://devcenter.heroku.com/articles/python-runtimes + Upgrade to a newer Python version as soon as possible, by + changing the version in your ${python_version_origin} file. + + For more information, see: + https://devcenter.heroku.com/articles/python-support#supported-python-versions EOF fi diff --git a/builds/build_python_runtime.sh b/builds/build_python_runtime.sh index 3da58a09c..0f442c6ff 100755 --- a/builds/build_python_runtime.sh +++ b/builds/build_python_runtime.sh @@ -21,7 +21,7 @@ function abort() { } case "${STACK:?}" in - heroku-22 | heroku-24) + heroku-20 | heroku-22 | heroku-24) SUPPORTED_PYTHON_VERSIONS=( "3.9" "3.10" @@ -30,16 +30,6 @@ case "${STACK:?}" in "3.13" ) ;; - heroku-20) - SUPPORTED_PYTHON_VERSIONS=( - "3.8" - "3.9" - "3.10" - "3.11" - "3.12" - "3.13" - ) - ;; *) abort "Unsupported stack '${STACK}'!" ;; @@ -63,7 +53,7 @@ case "${PYTHON_MAJOR_VERSION}" in # https://keybase.io/pablogsal/ GPG_KEY_FINGERPRINT='A035C8C19219BA821ECEA86B64E628F8D684696D' ;; - 3.8 | 3.9) + 3.9) # https://keybase.io/ambv/ GPG_KEY_FINGERPRINT='E3FF2839C048B25C084DEBE9B26995E310250568' ;; @@ -122,7 +112,7 @@ CONFIGURE_OPTS=( "--with-system-expat" ) -if [[ "${PYTHON_MAJOR_VERSION}" != +(3.8|3.9) ]]; then +if [[ "${PYTHON_MAJOR_VERSION}" != +(3.9) ]]; then CONFIGURE_OPTS+=( # Shared builds are beneficial for a number of reasons: # - Reduces the size of the build, since it avoids the duplication between @@ -147,7 +137,7 @@ if [[ "${PYTHON_MAJOR_VERSION}" != +(3.8|3.9) ]]; then ) fi -if [[ "${PYTHON_MAJOR_VERSION}" != +(3.8|3.9|3.10) ]]; then +if [[ "${PYTHON_MAJOR_VERSION}" != +(3.9|3.10) ]]; then CONFIGURE_OPTS+=( # Skip building the test modules, since we remove them after the build anyway. # This feature was added in Python 3.10+, however it wasn't until Python 3.11 @@ -170,7 +160,7 @@ fi # - https://github.com/docker-library/python/issues/810 # We only use `dpkg-buildflags` for Python versions where we build in shared mode (Python 3.9+), # since some of the options it enables interferes with the stripping of static libraries. -if [[ "${PYTHON_MAJOR_VERSION}" == +(3.8|3.9) ]]; then +if [[ "${PYTHON_MAJOR_VERSION}" == +(3.9) ]]; then EXTRA_CFLAGS='' LDFLAGS='-Wl,--strip-all' else @@ -182,7 +172,7 @@ CPU_COUNT="$(nproc)" make -j "${CPU_COUNT}" "EXTRA_CFLAGS=${EXTRA_CFLAGS}" "LDFLAGS=${LDFLAGS}" make install -if [[ "${PYTHON_MAJOR_VERSION}" == +(3.8|3.9) ]]; then +if [[ "${PYTHON_MAJOR_VERSION}" == +(3.9) ]]; then # On older versions of Python we're still building the static library, which has to be # manually stripped since the linker stripping enabled in LDFLAGS doesn't cover them. # We're using `--strip-unneeded` since `--strip-all` would remove the `.symtab` section @@ -233,7 +223,7 @@ LD_LIBRARY_PATH="${SRC_DIR}" "${SRC_DIR}/python" -m compileall -f --invalidation # (e.g. `python -m pydoc`) if needed. rm "${INSTALL_DIR}"/bin/{idle,pydoc}* # The 2to3 module and entrypoint was removed from the stdlib in Python 3.13. -if [[ "${PYTHON_MAJOR_VERSION}" == +(3.8|3.9|3.10|3.11|3.12) ]]; then +if [[ "${PYTHON_MAJOR_VERSION}" == +(3.9|3.10|3.11|3.12) ]]; then rm "${INSTALL_DIR}"/bin/2to3* fi diff --git a/lib/pip.sh b/lib/pip.sh index c6bedb92a..929063fb4 100644 --- a/lib/pip.sh +++ b/lib/pip.sh @@ -31,7 +31,7 @@ function pip::install_pip_setuptools_wheel() { # them installed. # - Most of the Python ecosystem has stopped installing them for Python 3.12+ already. # See the Python CNB's removal for more details: https://github.com/heroku/buildpacks-python/pull/243 - if [[ "${python_major_version}" == +(3.8|3.9|3.10|3.11|3.12) ]]; then + if [[ "${python_major_version}" == +(3.9|3.10|3.11|3.12) ]]; then meta_set "setuptools_version" "${SETUPTOOLS_VERSION}" meta_set "wheel_version" "${WHEEL_VERSION}" packages_to_install+=( diff --git a/lib/python_version.sh b/lib/python_version.sh index 6d008c849..f7bacb6ad 100644 --- a/lib/python_version.sh +++ b/lib/python_version.sh @@ -4,13 +4,15 @@ # however, it helps Shellcheck realise the options under which these functions will run. set -euo pipefail -LATEST_PYTHON_3_8="3.8.20" LATEST_PYTHON_3_9="3.9.21" LATEST_PYTHON_3_10="3.10.16" LATEST_PYTHON_3_11="3.11.11" LATEST_PYTHON_3_12="3.12.8" LATEST_PYTHON_3_13="3.13.1" +OLDEST_SUPPORTED_PYTHON_3_MINOR_VERSION=9 +NEWEST_SUPPORTED_PYTHON_3_MINOR_VERSION=13 + DEFAULT_PYTHON_FULL_VERSION="${LATEST_PYTHON_3_13}" DEFAULT_PYTHON_MAJOR_VERSION="${DEFAULT_PYTHON_FULL_VERSION%.*}" @@ -280,7 +282,7 @@ function python_version::resolve_python_version() { local major="${BASH_REMATCH[1]}" local minor="${BASH_REMATCH[2]}" - if ((major < 3 || (major == 3 && minor < 8))); then + if ((major < 3 || (major == 3 && minor < OLDEST_SUPPORTED_PYTHON_3_MINOR_VERSION))); then if [[ "${python_version_origin}" == "cached" ]]; then output::error <<-EOF Error: The cached Python version has reached end-of-life. @@ -292,14 +294,13 @@ function python_version::resolve_python_version() { and is therefore no longer receiving security updates: https://devguide.python.org/versions/#supported-versions - As such, it is no longer supported by this buildpack. - - Please upgrade to a newer Python version by creating a - '.python-version' file that contains a Python version like: - ${DEFAULT_PYTHON_MAJOR_VERSION} - - For a list of the supported Python versions, see: + As such, it's no longer supported by this buildpack: https://devcenter.heroku.com/articles/python-support#supported-python-versions + + Please upgrade to at least Python 3.${OLDEST_SUPPORTED_PYTHON_3_MINOR_VERSION} by creating a + .python-version file in the root directory of your app, + that contains a Python version like: + 3.${OLDEST_SUPPORTED_PYTHON_3_MINOR_VERSION} EOF else output::error <<-EOF @@ -309,20 +310,18 @@ function python_version::resolve_python_version() { therefore no longer receiving security updates: https://devguide.python.org/versions/#supported-versions - As such, it is no longer supported by this buildpack. - - Please upgrade to a newer Python version by updating the - version configured via the '${python_version_origin}' file. - - For a list of the supported Python versions, see: + As such, it's no longer supported by this buildpack: https://devcenter.heroku.com/articles/python-support#supported-python-versions + + Please upgrade to at least Python 3.${OLDEST_SUPPORTED_PYTHON_3_MINOR_VERSION} by changing the + version in your ${python_version_origin} file. EOF fi meta_set "failure_reason" "python-version::eol" exit 1 fi - if (((major == 3 && minor > 13) || major >= 4)); then + if (((major == 3 && minor > NEWEST_SUPPORTED_PYTHON_3_MINOR_VERSION) || major >= 4)); then if [[ "${python_version_origin}" == "cached" ]]; then output::error <<-EOF Error: The cached Python version isn't recognised. @@ -336,7 +335,14 @@ function python_version::resolve_python_version() { This can occur if you have downgraded the version of the buildpack to an older version. - Please switch back to a newer version of this buildpack. + Please switch back to a newer version of this buildpack: + https://devcenter.heroku.com/articles/managing-buildpacks#view-your-buildpacks + https://devcenter.heroku.com/articles/managing-buildpacks#classic-buildpacks-references + + Alternatively, request an older Python version by creating + a .python-version file in the root directory of your app, + that contains a Python version like: + 3.${NEWEST_SUPPORTED_PYTHON_3_MINOR_VERSION} EOF else output::error <<-EOF @@ -350,12 +356,12 @@ function python_version::resolve_python_version() { https://devcenter.heroku.com/articles/python-support#supported-python-versions If it has, make sure that you are using the latest version - of this buildpack, and have not pinned to an older release: + of this buildpack, and haven't pinned to an older release: https://devcenter.heroku.com/articles/managing-buildpacks#view-your-buildpacks https://devcenter.heroku.com/articles/managing-buildpacks#classic-buildpacks-references - Otherwise, switch to a supported version (such as Python ${DEFAULT_PYTHON_MAJOR_VERSION}) - by updating the version configured via the '${python_version_origin}' file. + Otherwise, switch to a supported version (such as Python 3.${NEWEST_SUPPORTED_PYTHON_3_MINOR_VERSION}) + by changing the version in your ${python_version_origin} file. EOF fi meta_set "failure_reason" "python-version::unknown-major" @@ -366,7 +372,6 @@ function python_version::resolve_python_version() { # Otherwise map major version specifiers to the latest patch release. case "${requested_python_version}" in *.*.*) echo "${requested_python_version}" ;; - 3.8) echo "${LATEST_PYTHON_3_8}" ;; 3.9) echo "${LATEST_PYTHON_3_9}" ;; 3.10) echo "${LATEST_PYTHON_3_10}" ;; 3.11) echo "${LATEST_PYTHON_3_11}" ;; diff --git a/spec/fixtures/pipenv_python_version_eol/Pipfile b/spec/fixtures/pipenv_python_version_eol/Pipfile index afe33e1b7..40c03e309 100644 --- a/spec/fixtures/pipenv_python_version_eol/Pipfile +++ b/spec/fixtures/pipenv_python_version_eol/Pipfile @@ -9,4 +9,4 @@ typing-extensions = "*" [dev-packages] [requires] -python_version = "3.7" +python_version = "3.8" diff --git a/spec/fixtures/pipenv_python_version_eol/Pipfile.lock b/spec/fixtures/pipenv_python_version_eol/Pipfile.lock index cf0460577..ef45647a8 100644 --- a/spec/fixtures/pipenv_python_version_eol/Pipfile.lock +++ b/spec/fixtures/pipenv_python_version_eol/Pipfile.lock @@ -1,11 +1,11 @@ { "_meta": { "hash": { - "sha256": "319488142f6df2cfe3244f5ebb99c88eaa0ef808d4560570175577ce045dd02e" + "sha256": "feaf6b91bd5a191f779b2c2199b3e328369c87e6a598f02a3ba6c76d877e176f" }, "pipfile-spec": 6, "requires": { - "python_version": "3.7" + "python_version": "3.8" }, "sources": [ { diff --git a/spec/fixtures/python_3.8/.python-version b/spec/fixtures/python_3.8/.python-version deleted file mode 100644 index 6a8981ea9..000000000 --- a/spec/fixtures/python_3.8/.python-version +++ /dev/null @@ -1,2 +0,0 @@ -# Comments are supported -3.8 diff --git a/spec/fixtures/python_3.8/requirements.txt b/spec/fixtures/python_3.8/requirements.txt deleted file mode 100644 index eec3a2223..000000000 --- a/spec/fixtures/python_3.8/requirements.txt +++ /dev/null @@ -1,2 +0,0 @@ -# This package has been picked since it has no dependencies and is small/fast to install. -typing-extensions==4.12.2 diff --git a/spec/fixtures/python_version_eol/.python-version b/spec/fixtures/python_version_eol/.python-version index 81cd8ab6c..2237ff9e6 100644 --- a/spec/fixtures/python_version_eol/.python-version +++ b/spec/fixtures/python_version_eol/.python-version @@ -4,5 +4,5 @@ # So are empty lines, and leading/trailing whitespace. - 3.7 + 3.8 diff --git a/spec/fixtures/python_version_outdated/.python-version b/spec/fixtures/python_version_outdated/.python-version index a5c4c7633..30291cba2 100644 --- a/spec/fixtures/python_version_outdated/.python-version +++ b/spec/fixtures/python_version_outdated/.python-version @@ -1 +1 @@ -3.9.0 +3.10.0 diff --git a/spec/fixtures/python_version_outdated_and_deprecated/runtime.txt b/spec/fixtures/python_version_outdated_and_deprecated/runtime.txt index 73b1cf81d..f72c5111f 100644 --- a/spec/fixtures/python_version_outdated_and_deprecated/runtime.txt +++ b/spec/fixtures/python_version_outdated_and_deprecated/runtime.txt @@ -1 +1 @@ -python-3.8.0 +python-3.9.0 diff --git a/spec/hatchet/pipenv_spec.rb b/spec/hatchet/pipenv_spec.rb index f6d3ba1ab..4a44a7825 100644 --- a/spec/hatchet/pipenv_spec.rb +++ b/spec/hatchet/pipenv_spec.rb @@ -80,6 +80,22 @@ remote: -----> Using Python 3.9.0 specified in Pipfile.lock remote: -----> Installing Python 3.9.0 remote: + remote: ! Warning: Support for Python 3.9 is ending soon! + remote: ! + remote: ! Python 3.9 will reach its upstream end-of-life in October 2025, + remote: ! at which point it will no longer receive security updates: + remote: ! https://devguide.python.org/versions/#supported-versions + remote: ! + remote: ! As such, support for Python 3.9 will be removed from this + remote: ! buildpack on 7th January 2026. + remote: ! + remote: ! Upgrade to a newer Python version as soon as possible, by + remote: ! changing the version in your Pipfile.lock file. + remote: ! + remote: ! For more information, see: + remote: ! https://devcenter.heroku.com/articles/python-support#supported-python-versions + remote: + remote: remote: ! Warning: A Python security update is available! remote: ! remote: ! Upgrade as soon as possible to: Python #{LATEST_PYTHON_3_9} @@ -266,21 +282,19 @@ app.deploy do |app| expect(clean_output(app.output)).to match(Regexp.new(<<~OUTPUT)) remote: -----> Python app detected - remote: -----> Using Python 3.7 specified in Pipfile.lock + remote: -----> Using Python 3.8 specified in Pipfile.lock remote: remote: ! Error: The requested Python version has reached end-of-life. remote: ! - remote: ! Python 3.7 has reached its upstream end-of-life, and is + remote: ! Python 3.8 has reached its upstream end-of-life, and is remote: ! therefore no longer receiving security updates: remote: ! https://devguide.python.org/versions/#supported-versions remote: ! - remote: ! As such, it is no longer supported by this buildpack. - remote: ! - remote: ! Please upgrade to a newer Python version by updating the - remote: ! version configured via the 'Pipfile.lock' file. - remote: ! - remote: ! For a list of the supported Python versions, see: + remote: ! As such, it's no longer supported by this buildpack: remote: ! https://devcenter.heroku.com/articles/python-support#supported-python-versions + remote: ! + remote: ! Please upgrade to at least Python 3.9 by changing the + remote: ! version in your Pipfile.lock file. remote: remote: ! Push rejected, failed to compile Python app. OUTPUT diff --git a/spec/hatchet/poetry_spec.rb b/spec/hatchet/poetry_spec.rb index 6d3786bd8..0429c0310 100644 --- a/spec/hatchet/poetry_spec.rb +++ b/spec/hatchet/poetry_spec.rb @@ -199,6 +199,22 @@ remote: -----> Using Python 3.9.0 specified in .python-version remote: -----> Installing Python 3.9.0 remote: + remote: ! Warning: Support for Python 3.9 is ending soon! + remote: ! + remote: ! Python 3.9 will reach its upstream end-of-life in October 2025, + remote: ! at which point it will no longer receive security updates: + remote: ! https://devguide.python.org/versions/#supported-versions + remote: ! + remote: ! As such, support for Python 3.9 will be removed from this + remote: ! buildpack on 7th January 2026. + remote: ! + remote: ! Upgrade to a newer Python version as soon as possible, by + remote: ! changing the version in your .python-version file. + remote: ! + remote: ! For more information, see: + remote: ! https://devcenter.heroku.com/articles/python-support#supported-python-versions + remote: + remote: remote: ! Warning: A Python security update is available! remote: ! remote: ! Upgrade as soon as possible to: Python #{LATEST_PYTHON_3_9} diff --git a/spec/hatchet/python_update_warning_spec.rb b/spec/hatchet/python_update_warning_spec.rb index ede46f2f0..09123a5b6 100644 --- a/spec/hatchet/python_update_warning_spec.rb +++ b/spec/hatchet/python_update_warning_spec.rb @@ -7,58 +7,38 @@ # patch releases will bundle older pip, and the buildpack uses that pip during bootstrapping. RSpec.describe 'Python update warnings' do context 'with a runtime.txt containing an outdated patch version that is also a deprecated major version' do - let(:allow_failure) { false } - let(:app) { Hatchet::Runner.new('spec/fixtures/python_version_outdated_and_deprecated', allow_failure:) } + let(:app) { Hatchet::Runner.new('spec/fixtures/python_version_outdated_and_deprecated') } - context 'when using Heroku-20', stacks: %w[heroku-20] do - it 'warns about both the deprecated major version and the patch update' do - app.deploy do |app| - expect(clean_output(app.output)).to include(<<~OUTPUT) - remote: -----> Python app detected - remote: -----> Using Python 3.8.0 specified in runtime.txt - remote: -----> Installing Python 3.8.0 - remote: - remote: ! Warning: Support for Python 3.8 is ending soon! - remote: ! - remote: ! Python 3.8 reached its upstream end-of-life on 7th October 2024, and so - remote: ! no longer receives security updates: - remote: ! https://devguide.python.org/versions/#supported-versions - remote: ! - remote: ! Support for Python 3.8 will be removed from this buildpack on 7th January 2025. - remote: ! - remote: ! Upgrade to a newer Python version as soon as possible to keep your app secure. - remote: ! See: https://devcenter.heroku.com/articles/python-runtimes - remote: - remote: - remote: ! Warning: A Python security update is available! - remote: ! - remote: ! Upgrade as soon as possible to: Python #{LATEST_PYTHON_3_8} - remote: ! See: https://devcenter.heroku.com/articles/python-runtimes - remote: - remote: -----> Installing pip #{PIP_VERSION}, setuptools #{SETUPTOOLS_VERSION} and wheel #{WHEEL_VERSION} - OUTPUT - end - end - end - - context 'when using Heroku-22 or newer', stacks: %w[heroku-22 heroku-24] do - let(:allow_failure) { true } - - # We only support Python 3.8 on Heroku-20 and older. - it 'aborts the build without showing an update warning' do - app.deploy do |app| - expect(clean_output(app.output)).to include(<<~OUTPUT) - remote: -----> Python app detected - remote: -----> Using Python 3.8.0 specified in runtime.txt - remote: - remote: ! Error: Python 3.8.0 isn't available for this stack (#{app.stack}). - remote: ! - remote: ! For a list of the supported Python versions, see: - remote: ! https://devcenter.heroku.com/articles/python-support#supported-python-versions - remote: - remote: ! Push rejected, failed to compile Python app. - OUTPUT - end + it 'warns about both the deprecated major version and the patch update' do + app.deploy do |app| + expect(clean_output(app.output)).to include(<<~OUTPUT) + remote: -----> Python app detected + remote: -----> Using Python 3.9.0 specified in runtime.txt + remote: -----> Installing Python 3.9.0 + remote: + remote: ! Warning: Support for Python 3.9 is ending soon! + remote: ! + remote: ! Python 3.9 will reach its upstream end-of-life in October 2025, + remote: ! at which point it will no longer receive security updates: + remote: ! https://devguide.python.org/versions/#supported-versions + remote: ! + remote: ! As such, support for Python 3.9 will be removed from this + remote: ! buildpack on 7th January 2026. + remote: ! + remote: ! Upgrade to a newer Python version as soon as possible, by + remote: ! changing the version in your runtime.txt file. + remote: ! + remote: ! For more information, see: + remote: ! https://devcenter.heroku.com/articles/python-support#supported-python-versions + remote: + remote: + remote: ! Warning: A Python security update is available! + remote: ! + remote: ! Upgrade as soon as possible to: Python #{LATEST_PYTHON_3_9} + remote: ! See: https://devcenter.heroku.com/articles/python-runtimes + remote: + remote: -----> Installing pip #{PIP_VERSION}, setuptools #{SETUPTOOLS_VERSION} and wheel #{WHEEL_VERSION} + OUTPUT end end end @@ -70,12 +50,12 @@ app.deploy do |app| expect(clean_output(app.output)).to include(<<~OUTPUT) remote: -----> Python app detected - remote: -----> Using Python 3.9.0 specified in .python-version - remote: -----> Installing Python 3.9.0 + remote: -----> Using Python 3.10.0 specified in .python-version + remote: -----> Installing Python 3.10.0 remote: remote: ! Warning: A Python security update is available! remote: ! - remote: ! Upgrade as soon as possible to: Python #{LATEST_PYTHON_3_9} + remote: ! Upgrade as soon as possible to: Python #{LATEST_PYTHON_3_10} remote: ! See: https://devcenter.heroku.com/articles/python-runtimes remote: remote: -----> Installing pip #{PIP_VERSION}, setuptools #{SETUPTOOLS_VERSION} and wheel #{WHEEL_VERSION} diff --git a/spec/hatchet/python_version_spec.rb b/spec/hatchet/python_version_spec.rb index 43b098231..3b547f7ee 100644 --- a/spec/hatchet/python_version_spec.rb +++ b/spec/hatchet/python_version_spec.rb @@ -75,65 +75,39 @@ end end - context 'when .python-version contains Python 3.8' do - let(:allow_failure) { false } - let(:app) { Hatchet::Runner.new('spec/fixtures/python_3.8', allow_failure:) } - - context 'when using Heroku-20', stacks: %w[heroku-20] do - it 'builds with latest Python 3.8 but shows a deprecation warning' do - app.deploy do |app| - expect(clean_output(app.output)).to include(<<~OUTPUT) - remote: -----> Python app detected - remote: -----> Using Python 3.8 specified in .python-version - remote: -----> Installing Python #{LATEST_PYTHON_3_8} - remote: - remote: ! Warning: Support for Python 3.8 is ending soon! - remote: ! - remote: ! Python 3.8 reached its upstream end-of-life on 7th October 2024, and so - remote: ! no longer receives security updates: - remote: ! https://devguide.python.org/versions/#supported-versions - remote: ! - remote: ! Support for Python 3.8 will be removed from this buildpack on 7th January 2025. - remote: ! - remote: ! Upgrade to a newer Python version as soon as possible to keep your app secure. - remote: ! See: https://devcenter.heroku.com/articles/python-runtimes - remote: - remote: -----> Installing pip #{PIP_VERSION}, setuptools #{SETUPTOOLS_VERSION} and wheel #{WHEEL_VERSION} - remote: -----> Installing SQLite3 - remote: -----> Installing dependencies using 'pip install -r requirements.txt' - remote: Collecting typing-extensions==4.12.2 (from -r requirements.txt (line 2)) - OUTPUT - expect(app.run('python -V')).to include("Python #{LATEST_PYTHON_3_8}") - end - end - end - - context 'when using Heroku-22 or newer', stacks: %w[heroku-22 heroku-24] do - let(:allow_failure) { true } - - # We only support Python 3.8 on Heroku-20 and older. - it 'aborts the build with a version not available message' do - app.deploy do |app| - expect(clean_output(app.output)).to include(<<~OUTPUT) - remote: -----> Python app detected - remote: -----> Using Python 3.8 specified in .python-version - remote: - remote: ! Error: Python #{LATEST_PYTHON_3_8} isn't available for this stack (#{app.stack}). - remote: ! - remote: ! For a list of the supported Python versions, see: - remote: ! https://devcenter.heroku.com/articles/python-support#supported-python-versions - remote: - remote: ! Push rejected, failed to compile Python app. - OUTPUT - end - end - end - end - context 'when .python-version contains Python 3.9' do let(:app) { Hatchet::Runner.new('spec/fixtures/python_3.9') } - include_examples 'builds with the requested Python version', '3.9', LATEST_PYTHON_3_9 + it 'builds with Python 3.9 but shows a deprecation warning' do + app.deploy do |app| + expect(clean_output(app.output)).to include(<<~OUTPUT) + remote: -----> Python app detected + remote: -----> Using Python 3.9 specified in .python-version + remote: -----> Installing Python #{LATEST_PYTHON_3_9} + remote: + remote: ! Warning: Support for Python 3.9 is ending soon! + remote: ! + remote: ! Python 3.9 will reach its upstream end-of-life in October 2025, + remote: ! at which point it will no longer receive security updates: + remote: ! https://devguide.python.org/versions/#supported-versions + remote: ! + remote: ! As such, support for Python 3.9 will be removed from this + remote: ! buildpack on 7th January 2026. + remote: ! + remote: ! Upgrade to a newer Python version as soon as possible, by + remote: ! changing the version in your .python-version file. + remote: ! + remote: ! For more information, see: + remote: ! https://devcenter.heroku.com/articles/python-support#supported-python-versions + remote: + remote: -----> Installing pip #{PIP_VERSION}, setuptools #{SETUPTOOLS_VERSION} and wheel #{WHEEL_VERSION} + remote: -----> Installing SQLite3 + remote: -----> Installing dependencies using 'pip install -r requirements.txt' + remote: Collecting typing-extensions==4.12.2 (from -r requirements.txt (line 2)) + OUTPUT + expect(app.run('python -V')).to include("Python #{LATEST_PYTHON_3_9}") + end + end end context 'when .python-version contains Python 3.10' do @@ -252,21 +226,19 @@ app.deploy do |app| expect(clean_output(app.output)).to include(<<~OUTPUT) remote: -----> Python app detected - remote: -----> Using Python 3.7 specified in .python-version + remote: -----> Using Python 3.8 specified in .python-version remote: remote: ! Error: The requested Python version has reached end-of-life. remote: ! - remote: ! Python 3.7 has reached its upstream end-of-life, and is + remote: ! Python 3.8 has reached its upstream end-of-life, and is remote: ! therefore no longer receiving security updates: remote: ! https://devguide.python.org/versions/#supported-versions remote: ! - remote: ! As such, it is no longer supported by this buildpack. - remote: ! - remote: ! Please upgrade to a newer Python version by updating the - remote: ! version configured via the '.python-version' file. - remote: ! - remote: ! For a list of the supported Python versions, see: + remote: ! As such, it's no longer supported by this buildpack: remote: ! https://devcenter.heroku.com/articles/python-support#supported-python-versions + remote: ! + remote: ! Please upgrade to at least Python 3.9 by changing the + remote: ! version in your .python-version file. remote: remote: ! Push rejected, failed to compile Python app. OUTPUT @@ -293,12 +265,12 @@ remote: ! https://devcenter.heroku.com/articles/python-support#supported-python-versions remote: ! remote: ! If it has, make sure that you are using the latest version - remote: ! of this buildpack, and have not pinned to an older release: + remote: ! of this buildpack, and haven't pinned to an older release: remote: ! https://devcenter.heroku.com/articles/managing-buildpacks#view-your-buildpacks remote: ! https://devcenter.heroku.com/articles/managing-buildpacks#classic-buildpacks-references remote: ! remote: ! Otherwise, switch to a supported version (such as Python #{DEFAULT_PYTHON_MAJOR_VERSION}) - remote: ! by updating the version configured via the '.python-version' file. + remote: ! by changing the version in your .python-version file. remote: remote: ! Push rejected, failed to compile Python app. OUTPUT @@ -373,13 +345,11 @@ remote: ! therefore no longer receiving security updates: remote: ! https://devguide.python.org/versions/#supported-versions remote: ! - remote: ! As such, it is no longer supported by this buildpack. - remote: ! - remote: ! Please upgrade to a newer Python version by updating the - remote: ! version configured via the 'runtime.txt' file. - remote: ! - remote: ! For a list of the supported Python versions, see: + remote: ! As such, it's no longer supported by this buildpack: remote: ! https://devcenter.heroku.com/articles/python-support#supported-python-versions + remote: ! + remote: ! Please upgrade to at least Python 3.9 by changing the + remote: ! version in your runtime.txt file. remote: remote: ! Push rejected, failed to compile Python app. OUTPUT diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 2405d9303..af1ca38cf 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -9,7 +9,6 @@ FIXTURE_DIR = Pathname.new(__FILE__).parent.join('fixtures') -LATEST_PYTHON_3_8 = '3.8.20' LATEST_PYTHON_3_9 = '3.9.21' LATEST_PYTHON_3_10 = '3.10.16' LATEST_PYTHON_3_11 = '3.11.11'