mirror of
https://github.com/kennethreitz/heroku-buildpack-python.git
synced 2026-06-05 23:10:16 +00:00
fcf696b835
This adds support for the upcoming Heroku-20 stack. The Heroku-20 Dockerfile is identical to that for Heroku-18, other than the base image, and stack-related env var changes. The initial Python versions made available will be those in: https://devcenter.heroku.com/articles/python-support#supported-runtimes https://devcenter.heroku.com/articles/python-support#supported-pypy-runtimes ...minus CPython 2.7, since it's EOL. Which are: * `python-3.6.12` * `python-3.7.9` * `python-3.8.6` * `python-3.9.0` * `pypy2.7-7.3.2` * `pypy3.6-7.3.2` Note: Unlike CPython 2.7, the PyPy 2.7 branch is still supported: https://doc.pypy.org/en/latest/faq.html#how-long-will-pypy-support-python2 In addition, I've generated binaries for each patch release immediately prior to the latest versions (with the exception of 3.9.0, since there isn't one), otherwise it's not possible to run the "out of date Python" warning tests. The binaries were generated using the process here: https://github.com/heroku/heroku-buildpack-python/blob/main/builds/README.md Specifically: ``` make deploy-runtimes STACKS='heroku-20' \ RUNTIMES='python-3.6.11 python-3.6.12 python-3.7.8 python-3.7.9 python-3.8.5 python-3.8.6 python-3.9.0 pypy2.7-7.3.1 pypy2.7-7.3.2 pypy3.6-7.3.1 pypy3.6-7.3.2' \ ENV_FILE=... ``` Binaries for the GDAL/GEOS/PROJ feature have not been generated, since it's deprecated and due for removal shortly: https://help.heroku.com/D5INLB1A/python-s-build_with_geo_libraries-legacy-feature-is-now-deprecated Note: Like the Python 3.9.0 release, this uses the new S3 bucket, so apps will need to be using a recent version of the buildpack in order to build on Heroku-20: https://devcenter.heroku.com/articles/python-support#checking-the-python-buildpack-version Closes @W-7485877@.
262 lines
7.5 KiB
Bash
Executable File
262 lines
7.5 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
|
|
# Default Python Versions
|
|
# shellcheck source=bin/default_pythons
|
|
source "bin/default_pythons"
|
|
|
|
testPythonVersionUnspecified() {
|
|
compile "python_version_unspecified"
|
|
assertCaptured "Installing ${DEFAULT_PYTHON_VERSION}"
|
|
assertNotCaptured "security update"
|
|
assertCaptured "Installing pip 20.1.1, setuptools 47.1.1 and wheel 0.34.2"
|
|
assertCaptured "Installing SQLite3"
|
|
assertCapturedSuccess
|
|
}
|
|
|
|
testPython2_7() {
|
|
# Python 2.7 is EOL, so it has not been built for Heroku-20.
|
|
if [[ $STACK == "heroku-20" ]]; then
|
|
return
|
|
fi
|
|
compile "python2"
|
|
assertCaptured "Installing ${LATEST_27}"
|
|
assertCaptured "python-2-7-eol-faq";
|
|
assertNotCaptured "security update"
|
|
assertCaptured "Installing pip 20.1.1, setuptools 44.1.1 and wheel 0.34.2"
|
|
assertCaptured "Installing SQLite3"
|
|
assertCapturedSuccess
|
|
}
|
|
|
|
testPython2_7_warn() {
|
|
# Python 2.7 is EOL, so it has not been built for Heroku-20.
|
|
if [[ $STACK == "heroku-20" ]]; then
|
|
return
|
|
fi
|
|
compile "python2_warn"
|
|
assertCaptured "Installing python-2.7.15"
|
|
assertCaptured "python-2-7-eol-faq";
|
|
assertCaptured "Only the latest version"
|
|
assertCaptured "${LATEST_27}"
|
|
assertCapturedSuccess
|
|
}
|
|
|
|
testPython3_4() {
|
|
# Python 3.4 is EOL, so it has not been built for Heroku-20.
|
|
if [[ $STACK == "heroku-20" ]]; then
|
|
return
|
|
fi
|
|
compile "python3_4"
|
|
assertCaptured "Installing ${LATEST_34}"
|
|
assertNotCaptured "security update"
|
|
assertCaptured "Installing pip 19.1.1, setuptools 43.0.0 and wheel 0.33.6"
|
|
assertCaptured "Installing SQLite3"
|
|
# Can't use `assertCapturedSuccess` since Pip outputs a Python 3.4 EOL warning to stderr,
|
|
# and the newest Pip that works on Python 3.4 doesn't support `PIP_NO_PYTHON_VERSION_WARNING`.
|
|
assertCapturedSuccessWithStdErr
|
|
}
|
|
|
|
testPython3_4_warn() {
|
|
# Python 3.4 is EOL, so it has not been built for Heroku-20.
|
|
if [[ $STACK == "heroku-20" ]]; then
|
|
return
|
|
fi
|
|
compile "python3_4_warn"
|
|
assertCaptured "Installing python-3.4.9"
|
|
assertCaptured "security update!"
|
|
assertCaptured "${LATEST_34}"
|
|
# Can't use `assertCapturedSuccess` since Pip outputs a Python 3.4 EOL warning to stderr,
|
|
# and the newest Pip that works on Python 3.4 doesn't support `PIP_NO_PYTHON_VERSION_WARNING`.
|
|
assertCapturedSuccessWithStdErr
|
|
}
|
|
|
|
testPython3_5() {
|
|
# Python 3.5 is EOL, so it has not been built for Heroku-20.
|
|
if [[ $STACK == "heroku-20" ]]; then
|
|
return
|
|
fi
|
|
compile "python3_5"
|
|
assertCaptured "Installing ${LATEST_35}"
|
|
assertNotCaptured "security update"
|
|
assertCaptured "Installing pip 20.1.1, setuptools 47.1.1 and wheel 0.34.2"
|
|
assertCaptured "Installing SQLite3"
|
|
assertCapturedSuccess
|
|
}
|
|
|
|
testPython3_5_warn() {
|
|
# Python 3.5 is EOL, so it has not been built for Heroku-20.
|
|
if [[ $STACK == "heroku-20" ]]; then
|
|
return
|
|
fi
|
|
compile "python3_5_warn"
|
|
assertCaptured "Installing python-3.5.6"
|
|
assertCaptured "security update!"
|
|
assertCaptured "${LATEST_35}"
|
|
assertCapturedSuccess
|
|
}
|
|
|
|
testPython3_6() {
|
|
compile "python3_6"
|
|
assertCaptured "Installing ${LATEST_36}"
|
|
assertNotCaptured "security update"
|
|
assertCaptured "Installing pip 20.1.1, setuptools 47.1.1 and wheel 0.34.2"
|
|
assertCaptured "Installing SQLite3"
|
|
assertCapturedSuccess
|
|
}
|
|
|
|
testPython3_6_warn() {
|
|
compile "python3_6_warn"
|
|
assertCaptured "Installing python-3.6.11"
|
|
assertCaptured "security update!"
|
|
assertCaptured "${LATEST_36}"
|
|
assertCapturedSuccess
|
|
}
|
|
|
|
testPython3_7() {
|
|
# Python 3.7+ requires newer libssl than is present on Cedar-14.
|
|
if [[ "${STACK}" = "cedar-14" ]]; then
|
|
return
|
|
fi
|
|
compile "python3_7"
|
|
assertCaptured "Installing ${LATEST_37}"
|
|
assertNotCaptured "security update"
|
|
assertCaptured "Installing pip 20.1.1, setuptools 47.1.1 and wheel 0.34.2"
|
|
assertCaptured "Installing SQLite3"
|
|
assertCapturedSuccess
|
|
}
|
|
|
|
testPython3_7_warn() {
|
|
# Python 3.7+ requires newer libssl than is present on Cedar-14.
|
|
if [[ "${STACK}" = "cedar-14" ]]; then
|
|
return
|
|
fi
|
|
compile "python3_7_warn"
|
|
assertCaptured "Installing python-3.7.8"
|
|
assertCaptured "security update!"
|
|
assertCaptured "${LATEST_37}"
|
|
assertCapturedSuccess
|
|
}
|
|
|
|
testPython3_8() {
|
|
# Python 3.7+ requires newer libssl than is present on Cedar-14.
|
|
if [[ "${STACK}" = "cedar-14" ]]; then
|
|
return
|
|
fi
|
|
compile "python3_8"
|
|
assertCaptured "Installing ${LATEST_38}"
|
|
assertNotCaptured "security update"
|
|
assertCaptured "Installing pip 20.1.1, setuptools 47.1.1 and wheel 0.34.2"
|
|
assertCaptured "Installing SQLite3"
|
|
assertCapturedSuccess
|
|
}
|
|
|
|
testPython3_8_warn() {
|
|
# Python 3.7+ requires newer libssl than is present on Cedar-14.
|
|
if [[ "${STACK}" = "cedar-14" ]]; then
|
|
return
|
|
fi
|
|
compile "python3_8_warn"
|
|
assertCaptured "Installing python-3.8.5"
|
|
assertCaptured "security update!"
|
|
assertCaptured "${LATEST_38}"
|
|
assertCapturedSuccess
|
|
}
|
|
|
|
testPython3_9() {
|
|
# Cedar-14 is EOL, so we're not building new major Python versions for it.
|
|
if [[ "${STACK}" = "cedar-14" ]]; then
|
|
return
|
|
fi
|
|
compile "python3_9"
|
|
assertCaptured "Installing ${LATEST_39}"
|
|
assertNotCaptured "security update"
|
|
assertCaptured "Installing pip 20.1.1, setuptools 47.1.1 and wheel 0.34.2"
|
|
assertCaptured "Installing SQLite3"
|
|
assertCapturedSuccess
|
|
}
|
|
|
|
testPython3_9_warn() {
|
|
# Cedar-14 is EOL, so we're not building new major Python versions for it.
|
|
if [[ "${STACK}" = "cedar-14" ]]; then
|
|
return
|
|
fi
|
|
# Can't test the version warning until there is at least one old version of Python 3.9.
|
|
if [[ "${LATEST_39}" = "python-3.9.0" ]]; then
|
|
return
|
|
fi
|
|
compile "python3_9_warn"
|
|
assertCaptured "Installing python-3.9.0"
|
|
assertCaptured "security update!"
|
|
assertCaptured "${LATEST_39}"
|
|
assertCapturedSuccess
|
|
}
|
|
|
|
testPythonVersionInvalid() {
|
|
compile "python_version_invalid"
|
|
assertCaptured "Requested runtime (python-3.8.99) is not available for this stack"
|
|
assertCaptured "Aborting"
|
|
assertCapturedError
|
|
}
|
|
|
|
testPypy3_6() {
|
|
compile "pypy3_6"
|
|
assertCaptured "Installing ${LATEST_PYPY_36}"
|
|
assertNotCaptured "security update"
|
|
assertCaptured "Installing pip 20.1.1, setuptools 47.1.1 and wheel 0.34.2"
|
|
assertCapturedSuccess
|
|
}
|
|
|
|
testPypy3_6_warn() {
|
|
compile "pypy3_6_warn"
|
|
assertCaptured "Installing pypy3.6-7.3.1"
|
|
assertCaptured "security update!"
|
|
assertCaptured "${LATEST_PYPY_36}"
|
|
assertCapturedSuccess
|
|
}
|
|
|
|
testPypy2_7() {
|
|
compile "pypy2_7"
|
|
assertCaptured "Installing ${LATEST_PYPY_27}"
|
|
assertNotCaptured "security update"
|
|
assertCaptured "Installing pip 20.1.1, setuptools 44.1.1 and wheel 0.34.2"
|
|
assertCapturedSuccess
|
|
}
|
|
|
|
testPypy2_7_warn() {
|
|
compile "pypy2_7_warn"
|
|
assertCaptured "Installing pypy2.7-7.3.1"
|
|
assertCaptured "security update!"
|
|
assertCaptured "${LATEST_PYPY_27}"
|
|
assertCapturedSuccess
|
|
}
|
|
|
|
testStickyPythonVersion() {
|
|
local cache_dir="$(mktmpdir)"
|
|
compile "python3_6_warn" "$cache_dir"
|
|
assertCaptured "Installing python-3.6.11"
|
|
assertCapturedSuccess
|
|
compile "python_version_unspecified" "$cache_dir"
|
|
assertNotCaptured "Installing python"
|
|
assertCaptured "security update!"
|
|
assertCapturedSuccess
|
|
# Whilst this file seems like an implementation detail (so something that should
|
|
# not be tested), we must guarantee the filename remains consistent for backwards
|
|
# compatibility across buildpack versions for already-built apps.
|
|
assertFile "python-3.6.11" ".heroku/python-version"
|
|
}
|
|
|
|
testPythonVersionChange() {
|
|
local cache_dir="$(mktmpdir)"
|
|
compile "python3_6_warn" "$cache_dir"
|
|
assertCaptured "Installing python-3.6.11"
|
|
assertCapturedSuccess
|
|
compile "python3_6" "$cache_dir"
|
|
assertCaptured "Found python-3.6.11, removing"
|
|
assertCapturedSuccess
|
|
}
|
|
|
|
pushd $(dirname 0) >/dev/null
|
|
popd >/dev/null
|
|
|
|
source $(pwd)/test/utils
|
|
source $(pwd)/test/shunit2
|