diff --git a/CHANGELOG.md b/CHANGELOG.md index d9c2873fe8bbb501c5fc2cd59b832712e969d3a4..f36c0a921d6b2633a9376e52d0c928f9f6df96be 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,17 @@ # Python Buildpack Changelog +# 124 + +Update buildpack to automatically install [dev-packages] (Pipenv) during Heroku CI builds. + +# 123 + +Update gunicorn init.d script to allow overrides. + +# 122 + +Update default Python to v3.6.4. + # 121 Update default Python to v3.6.3. diff --git a/README.md b/README.md index df808ebe5d667d2de7aea58d79a8872a438400d9..7ec68184e0f42f9a9390700ce6bb979b34a490bb 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ Deploying a Python application couldn't be easier: $ git push heroku master … -----> Python app detected - -----> Installing python-3.6.3 + -----> Installing python-3.6.4 -----> Installing pip -----> Installing requirements with latest pipenv… ... @@ -58,7 +58,7 @@ Or, more specifically: Runtime options include: -- `python-3.6.3` +- `python-3.6.4` - `python-2.7.14` - `pypy-5.7.1` (unsupported, experimental) - `pypy3-5.5.1` (unsupported, experimental) diff --git a/bin/compile b/bin/compile index f43ebf1bc0ece4dcbad61da6e427e65775bd333c..0466e8e65b30b6ce10dd5e0b0f95b60da0f1b9ab 100755 --- a/bin/compile +++ b/bin/compile @@ -34,8 +34,8 @@ ENV_DIR=$3 export BUILD_DIR CACHE_DIR ENV_DIR # Python defaults -DEFAULT_PYTHON_VERSION="python-3.6.3" -LATEST_3="python-3.6.3" +DEFAULT_PYTHON_VERSION="python-3.6.4" +LATEST_3="python-3.6.4" LATEST_2="python-2.7.14" DEFAULT_PYTHON_STACK="cedar-14" diff --git a/bin/steps/pip-install b/bin/steps/pip-install index 8d4d144cfb4ffe4d240e9f4d6e7b67d3b9964f78..be92bd14d457e9b55dd1b5f6fec7646c769fe9d9 100755 --- a/bin/steps/pip-install +++ b/bin/steps/pip-install @@ -1,11 +1,17 @@ #!/usr/bin/env bash +# shellcheck source=bin/utils +source $BIN_DIR/utils + if [ ! "$SKIP_PIP_INSTALL" ]; then # Install dependencies with Pip. puts-step "Installing requirements with pip" set +e + + # Measure that we're using pip. + mcount "tool.pip" /app/.heroku/python/bin/pip install -r "$BUILD_DIR/requirements.txt" --exists-action=w --src=/app/.heroku/src --disable-pip-version-check --no-cache-dir 2>&1 | tee "$WARNINGS_LOG" | cleanup | indent PIP_STATUS="${PIPESTATUS[0]}" @@ -23,4 +29,12 @@ if [ ! "$SKIP_PIP_INSTALL" ]; then /app/.heroku/python/bin/pip freeze --disable-pip-version-check > .heroku/python/requirements-installed.txt echo + + # Install test dependencies, for CI. + if [ "$INSTALL_TEST" ]; then + if [[ -f "$1/requirements-test.txt" ]]; then + puts-step "Installing test dependencies…" + /app/.heroku/python/bin/pip install -r "$1/requirements-test.txt" --exists-action=w --src=./.heroku/src --disable-pip-version-check --no-cache-dir 2>&1 | cleanup | indent + fi + fi fi diff --git a/bin/steps/pipenv b/bin/steps/pipenv index db2cf14710ed8c4421d9dfe0ff495d2795b69ab6..5e050f740938ac88539ae485ed49d04682fac2d5 100644 --- a/bin/steps/pipenv +++ b/bin/steps/pipenv @@ -2,22 +2,32 @@ # export CLINT_FORCE_COLOR=1 # export PIPENV_FORCE_COLOR=1 +# shellcheck source=bin/utils +source $BIN_DIR/utils # Pipenv support (Generate requriements.txt with pipenv). if [[ -f Pipfile ]]; then if [[ ! -f requirements.txt ]]; then puts-step "Installing requirements with latest Pipenv…" + # Measure that we're using Pipenv. + mcount "tool.pipenv" + # Install pipenv. /app/.heroku/python/bin/pip install pipenv --upgrade &> /dev/null + # Install the dependencies. if [[ ! -f Pipfile.lock ]]; then /app/.heroku/python/bin/pipenv install --system --skip-lock 2>&1 | indent else /app/.heroku/python/bin/pipenv install --system --deploy 2>&1 | indent fi - # Install the dependencies. + # Install the test dependencies, for CI. + if [ "$INSTALL_TEST" ]; then + puts-step "Installing test dependencies…" + /app/.heroku/python/bin/pipenv install --dev --system --deploy 2>&1 | cleanup | indent + fi # Skip pip install, later. export SKIP_PIP_INSTALL=1 diff --git a/bin/test-compile b/bin/test-compile index d19814dbbe6bd55413a972fd0ed711ed89bc2c57..fa4a6580a3e7eb2158165f47cc46f37ee1d5e6b2 100755 --- a/bin/test-compile +++ b/bin/test-compile @@ -6,8 +6,8 @@ BIN_DIR=$(cd "$(dirname "$0")" || return; pwd) # absolute path # shellcheck source=bin/utils source "$BIN_DIR/utils" -DISABLE_COLLECTSTATIC=1 "$(dirname "${0:-}")/compile" "$1" "$2" "$3" +# Locale support for Pipenv. +export LC_ALL=C.UTF-8 +export LANG=C.UTF-8 -if [[ -f "$1/requirements-test.txt" ]]; then - /app/.heroku/python/bin/pip install -r "$1/requirements-test.txt" --exists-action=w --src=./.heroku/src --disable-pip-version-check --no-cache-dir 2>&1 | cleanup | indent -fi +DISABLE_COLLECTSTATIC=1 INSTALL_TEST=1 "$(dirname "${0:-}")/compile" "$1" "$2" "$3" \ No newline at end of file diff --git a/builds/runtimes/python-3.6.4 b/builds/runtimes/python-3.6.4 new file mode 100755 index 0000000000000000000000000000000000000000..d1a93dfb0b180462bb1f85893bacf307f43ffb8b --- /dev/null +++ b/builds/runtimes/python-3.6.4 @@ -0,0 +1,21 @@ +#!/usr/bin/env bash +# Build Path: /app/.heroku/python/ +# Build Deps: libraries/sqlite + +OUT_PREFIX=$1 + +echo "Building Python…" +SOURCE_TARBALL='https://python.org/ftp/python/3.6.4/Python-3.6.4.tgz' +curl -L $SOURCE_TARBALL | tar xz +mv Python-3.6.4 src +cd src + +./configure --prefix=$OUT_PREFIX --with-ensurepip=no +make +make install + +# Remove unneeded test directories, similar to the official Docker Python images: +# https://github.com/docker-library/python +find "${OUT_PREFIX}" \( -type d -a \( -name test -o -name tests \) \) -exec rm -rf '{}' + + +ln $OUT_PREFIX/bin/python3 $OUT_PREFIX/bin/python diff --git a/test/run b/test/run index 8c203d66029f27e559215320fb9bcfa6da20accc..62e902f42632fc966c719e203ba91ae8cc8b274a 100755 --- a/test/run +++ b/test/run @@ -12,7 +12,7 @@ testPipenvLock() { testPipenvVersion() { compile "pipenv-version" - assertCaptured "3.6.3" + assertCaptured "3.6.4" assertCapturedSuccess } @@ -78,7 +78,7 @@ testPython2() { testPython3() { compile "python3" - assertCaptured "python-3.6.3" + assertCaptured "python-3.6.4" assertCapturedSuccess } diff --git a/test/shunit2 b/test/shunit2 index 8862ffd4910d916add1cf232431c7fa5c34aaffd..4d0940b3b37838c7bd4f73e31b8f7256894a4c89 100755 --- a/test/shunit2 +++ b/test/shunit2 @@ -25,9 +25,9 @@ SHUNIT_ERROR=2 # enable strict mode by default SHUNIT_STRICT=${SHUNIT_STRICT:-${SHUNIT_TRUE}} -_shunit_warn() { echo "shunit2:WARN $@" >&2; } -_shunit_error() { echo "shunit2:ERROR $@" >&2; } -_shunit_fatal() { echo "shunit2:FATAL $@" >&2; exit ${SHUNIT_ERROR}; } +_shunit_warn() { echo "shunit2:WARN $*" >&2; } +_shunit_error() { echo "shunit2:ERROR $*" >&2; } +_shunit_fatal() { echo "shunit2:FATAL $*" >&2; exit ${SHUNIT_ERROR}; } # specific shell checks if [ -n "${ZSH_VERSION:-}" ]; then diff --git a/test/utils b/test/utils index 2332c708f38131fb51947f340a331c381e4dbdc8..1e079d29b9c442f531f0e320207dd70a397a349e 100644 --- a/test/utils +++ b/test/utils @@ -36,7 +36,7 @@ capture() LAST_COMMAND="$@" - $@ >${STD_OUT} 2>${STD_ERR} + "$@" >${STD_OUT} 2>${STD_ERR} RETURN=$? rtrn=${RETURN} # deprecated } diff --git a/vendor/python.gunicorn.sh b/vendor/python.gunicorn.sh index 164ca0759f4d797519a8342b90fc9274582a6481..3a91e3ac17dfb2644051e05426e02f122eceead9 100755 --- a/vendor/python.gunicorn.sh +++ b/vendor/python.gunicorn.sh @@ -1,2 +1,5 @@ # Automatic configuration for Gunicorn's ForwardedAllowIPS setting. export FORWARDED_ALLOW_IPS='*' + +# Automatic configuration for Gunicorn's stdout access log setting. +export GUNICORN_CMD_ARGS=${GUNICORN_CMD_ARGS:-"--access-logfile -"} diff --git a/vendor/shunit2 b/vendor/shunit2 index 9ec6c88bb5fbdcb49861a56ca255db0f5f9f2e4a..efa373d7ce57f74149a54020169f6400df23bbc8 100755 --- a/vendor/shunit2 +++ b/vendor/shunit2 @@ -25,9 +25,9 @@ SHUNIT_ERROR=2 # enable strict mode by default SHUNIT_STRICT=${SHUNIT_STRICT:-${SHUNIT_TRUE}} -_shunit_warn() { echo "shunit2:WARN $@" >&2; } -_shunit_error() { echo "shunit2:ERROR $@" >&2; } -_shunit_fatal() { echo "shunit2:FATAL $@" >&2; exit ${SHUNIT_ERROR}; } +_shunit_warn() { echo "shunit2:WARN $*" >&2; } +_shunit_error() { echo "shunit2:ERROR $*" >&2; } +_shunit_fatal() { echo "shunit2:FATAL $*" >&2; exit ${SHUNIT_ERROR}; } # specific shell checks if [ -n "${ZSH_VERSION:-}" ]; then diff --git a/vendor/test-utils b/vendor/test-utils index 44d04def99957d3b568373505f13c23eb1736df0..5729707009c3366853ecf9b4712b790406b3f9e0 100644 --- a/vendor/test-utils +++ b/vendor/test-utils @@ -36,7 +36,7 @@ capture() LAST_COMMAND="$@" - $@ >${STD_OUT} 2>${STD_ERR} + "$@" >${STD_OUT} 2>${STD_ERR} RETURN=$? rtrn=${RETURN} # deprecated }