Files
Ed Morley fc6698e597 Update pip to 20.1.1 (#1030)
Updates pip from 20.0.2 to 20.1.1 for Python 2.7 and Python 3.5+:
https://pip.pypa.io/en/stable/news/#id40

The version used for Python 3.4 remains unchanged at 19.1.1, since it's
the last version of pip that supports it.

Pip has been updated to 20.1.1 rather than the recently released 20.2,
since the latter has a few regressions and even though these will be
fixed shortly in 20.2.1, we should let the changes soak for longer
before picking them up.

The `PIP_NO_PYTHON_VERSION_WARNING` environment variable has been set
(equivalent to passing `--no-python-version-warning`) to prevent the
Python 2.7 EOL warnings added in pip 20.1 from spamming the build log:
https://github.com/pypa/pip/blob/20.1.1/src/pip/_internal/cli/base_command.py#L139-L154

This was set via environment variable rather than CLI flag, since:
* otherwise we'd have to pass it to every pip invocation
* older pip (such as the 19.1.1 used by Python 3.4) doesn't support this
  option and would error out due to an unknown CLI flag being passed,
  unless we added conditional flags throughout.

The new pip wheel was uploaded to S3 using:

```
$ pip download --no-cache pip==20.1.1
Collecting pip==20.1.1
  Downloading pip-20.1.1-py2.py3-none-any.whl (1.5 MB)
  Saved ./pip-20.1.1-py2.py3-none-any.whl
Successfully downloaded pip

$ aws s3 sync . s3://lang-python/common/ --exclude "*" --include "*.whl" --acl public-read --dryrun
(dryrun) upload: ./pip-20.1.1-py2.py3-none-any.whl to s3://lang-python/common/pip-20.1.1-py2.py3-none-any.whl

$ aws s3 sync . s3://lang-python/common/ --exclude "*" --include "*.whl" --acl public-read
upload: ./pip-20.1.1-py2.py3-none-any.whl to s3://lang-python/common/pip-20.1.1-py2.py3-none-any.whl
```

Fixes #1005.
@W-7659489@
2020-08-03 19:45:41 +01:00

189 lines
7.3 KiB
Bash
Executable File

#!/usr/bin/env bash
set +e
runtime-fixer runtime.txt
PYTHON_VERSION=$(cat runtime.txt)
# The location of the pre-compiled python binary.
VENDORED_PYTHON="${VENDOR_URL}/runtimes/$PYTHON_VERSION.tar.gz"
SECURITY_UPDATE="Python has released a security update! Please consider upgrading to"
ONLY_SUPPORTED_2_VERSION="Only the latest version of Python 2 is supported on the platform. Please consider upgrading to"
PYTHON_2_EOL_UPDATE="Python 2 has reached it's community EOL. Upgrade your Python runtime to maintain a secure application as soon as possible."
# check if runtime exists
if curl --output /dev/null --silent --head --fail "$VENDORED_PYTHON"; then
if [[ "$PYTHON_VERSION" == $PY38* ]]; then
# do things to alert the user of security release available
if [ "$PYTHON_VERSION" != "$LATEST_38" ]; then
puts-warn "$SECURITY_UPDATE" "$LATEST_38"
echo " Learn More: https://devcenter.heroku.com/articles/python-runtimes"
fi
fi
if [[ "$PYTHON_VERSION" == $PY37* ]]; then
# do things to alert the user of security release available
if [ "$PYTHON_VERSION" != "$LATEST_37" ]; then
puts-warn "$SECURITY_UPDATE" "$LATEST_37"
echo " Learn More: https://devcenter.heroku.com/articles/python-runtimes"
fi
fi
if [[ "$PYTHON_VERSION" == $PY36* ]]; then
# security update note
if [ "$PYTHON_VERSION" != "$LATEST_36" ]; then
puts-warn "$SECURITY_UPDATE" "$LATEST_36"
echo " Learn More: https://devcenter.heroku.com/articles/python-runtimes"
fi
fi
if [[ "$PYTHON_VERSION" == $PY35* ]]; then
# security update note
if [ "$PYTHON_VERSION" != "$LATEST_35" ]; then
puts-warn "$SECURITY_UPDATE" "$LATEST_35"
echo " Learn More: https://devcenter.heroku.com/articles/python-runtimes"
fi
fi
if [[ "$PYTHON_VERSION" == $PY34* ]]; then
# security update note
if [ "$PYTHON_VERSION" != "$LATEST_34" ]; then
puts-warn "$SECURITY_UPDATE" "$LATEST_34"
echo " Learn More: https://devcenter.heroku.com/articles/python-runtimes"
fi
fi
if [[ "$PYTHON_VERSION" == $PY27* ]]; then
# security update note
if [[ "$(date "+%Y")" -gt "2019" ]]; then
puts-warn "$PYTHON_2_EOL_UPDATE"
echo " Learn More: https://devcenter.heroku.com/articles/python-2-7-eol-faq"
fi
if [ "$PYTHON_VERSION" != "$LATEST_27" ]; then
puts-warn "$ONLY_SUPPORTED_2_VERSION" "$LATEST_27"
echo " Learn More: https://devcenter.heroku.com/articles/python-runtimes"
fi
fi
if [[ "$PYTHON_VERSION" == $PYPY27* ]]; then
# security update note
if [ "$PYTHON_VERSION" != "$PYPY_27" ]; then
puts-warn "Could not find that Pypy version. Did you mean" "${PYPY_27}?"
echo " Learn More: https://devcenter.heroku.com/articles/python-runtimes"
fi
fi
if [[ "$PYTHON_VERSION" == $PYPY36* ]]; then
# security update note
if [ "$PYTHON_VERSION" != "$PYPY_36" ]; then
puts-warn "Could not find that Pypy version. Did you mean" "${PYPY_36}?"
echo " Learn More: https://devcenter.heroku.com/articles/python-runtimes"
fi
fi
else
puts-warn "Requested runtime ($PYTHON_VERSION) is not available for this stack ($STACK)."
puts-warn "Aborting. More info: https://devcenter.heroku.com/articles/python-support"
exit 1
fi
if [[ "$STACK" != "$CACHED_PYTHON_STACK" ]]; then
puts-step "Stack has changed from $CACHED_PYTHON_STACK to $STACK, clearing cache"
rm -fr .heroku/python-stack .heroku/python-version .heroku/python .heroku/vendor .heroku/python .heroku/python-sqlite3-version
fi
if [ -f .heroku/python-version ]; then
if [ ! "$(cat .heroku/python-version)" = "$PYTHON_VERSION" ]; then
puts-step "Found $(cat .heroku/python-version), removing"
rm -fr .heroku/python
else
SKIP_INSTALL=1
fi
fi
# Check if we should reinstall python dependencies
if [[ ! -f "$CACHE_DIR/.heroku/requirements.txt" ]]; then
# IF there's no cached dependencies, update cached version of requirements.txt
# This should only run for new apps and first deploys after this update
cp -R "$BUILD_DIR/requirements.txt" "$CACHE_DIR/.heroku/requirements.txt"
else
# IF there IS a cached directory, check for differences with the new one
if ! diff "$BUILD_DIR/requirements.txt" "$CACHE_DIR/.heroku/requirements.txt" &> /dev/null; then
puts-step "Requirements file has been changed, clearing cached dependencies"
# if there are any differences, clear the Python cache
# Installing Python over again does not take noticably more time
cp -R "$BUILD_DIR/requirements.txt" "$CACHE_DIR/.heroku/requirements.txt"
rm -rf .heroku/python
unset SKIP_INSTALL
else
puts-step "No change in requirements detected, installing from cache"
fi
fi
if [ ! "$SKIP_INSTALL" ]; then
puts-step "Installing $PYTHON_VERSION"
# Prepare destination directory.
mkdir -p .heroku/python
mcount "version.python.$PYTHON_VERSION"
if ! curl "${VENDORED_PYTHON}" -s | tar zxv -C .heroku/python &> /dev/null; then
puts-warn "Requested runtime ($PYTHON_VERSION) is not available for this stack ($STACK)."
puts-warn "Aborting. More info: https://devcenter.heroku.com/articles/python-support"
exit 1
fi
# Record for future reference.
echo "$PYTHON_VERSION" > .heroku/python-version
echo "$STACK" > .heroku/python-stack
hash -r
fi
set -e
PIP_VERSION='20.1.1'
# Must use setuptools <47.2.0 until we fix:
# https://github.com/heroku/heroku-buildpack-python/issues/1006
SETUPTOOLS_VERSION='47.1.1'
WHEEL_VERSION='0.34.2'
if [[ "${PYTHON_VERSION}" == ${PY34}* ]]; then
# Python 3.4 support was dropped in pip 19.2+, setuptools 44+ and wheel 0.34+.
PIP_VERSION='19.1.1'
SETUPTOOLS_VERSION='43.0.0'
WHEEL_VERSION='0.33.6'
elif [[ "${PYTHON_VERSION}" == ${PY27}* || "${PYTHON_VERSION}" == ${PYPY27}* ]]; then
# Python 2.7 support was dropped in setuptools 45+.
SETUPTOOLS_VERSION='44.1.1'
fi
# We don't use get-pip.py, since:
# - it uses `--force-reinstall`, which is unnecessary here and slows down repeat builds
# - it means downloading pip twice (once embedded in get-pip.py, and again during
# the install, since get-pip.py can't install the embedded version directly)
# - we would still have to manage several versions of get-pip.py, to support older Pythons.
# Instead, we use the pip wheel to install itself, using the method described here:
# https://github.com/pypa/pip/issues/2351#issuecomment-69994524
PIP_WHEEL_FILENAME="pip-${PIP_VERSION}-py2.py3-none-any.whl"
PIP_WHEEL_URL="https://lang-python.s3.amazonaws.com/common/${PIP_WHEEL_FILENAME}"
PIP_WHEEL="${TMPDIR:-/tmp}/${PIP_WHEEL_FILENAME}"
if ! curl -sSf "${PIP_WHEEL_URL}" -o "$PIP_WHEEL"; then
mcount "failure.python.download-pip"
puts-warn "Failed to download pip"
exit 1
fi
if [[ -f "$BUILD_DIR/Pipfile" ]]; then
# The buildpack is pinned to old pipenv, which requires older pip.
# Pip 9.0.2 doesn't support installing itself from a wheel, so we have to use split
# versions here (ie: installer pip version different from target pip version).
PIP_VERSION='9.0.2'
PIP_TO_INSTALL="pip==${PIP_VERSION}"
else
PIP_TO_INSTALL="${PIP_WHEEL}"
fi
puts-step "Installing pip ${PIP_VERSION}, setuptools ${SETUPTOOLS_VERSION} and wheel ${WHEEL_VERSION}"
/app/.heroku/python/bin/python "${PIP_WHEEL}/pip" install --quiet --disable-pip-version-check --no-cache \
"${PIP_TO_INSTALL}" "setuptools==${SETUPTOOLS_VERSION}" "wheel==${WHEEL_VERSION}"
hash -r