1#!/bin/bash 2 3set -ex 4 5function get_source_version() { 6 grep "__version__ = '.*'" python/google/protobuf/__init__.py | sed -r "s/__version__ = '(.*)'/\1/" 7} 8 9function run_install_test() { 10 local VERSION=$1 11 local PYTHON=$2 12 local PYPI=$3 13 14 virtualenv -p `which $PYTHON` test-venv 15 16 # Intentionally put a broken protoc in the path to make sure installation 17 # doesn't require protoc installed. 18 touch test-venv/bin/protoc 19 chmod +x test-venv/bin/protoc 20 21 source test-venv/bin/activate 22 (pip install -i ${PYPI} protobuf==${VERSION} --no-cache-dir) || (retry_pip_install ${PYPI} ${VERSION}) 23 deactivate 24 rm -fr test-venv 25} 26 27function retry_pip_install() { 28 local PYPI=$1 29 local VERSION=$2 30 31 read -p "pip install failed, possibly due to delay between upload and availability on pip. Retry? [y/n]" -r 32 echo 33 if [[ ! $REPLY =~ ^[Yy]$ ]]; then 34 exit 1 35 fi 36 37 (pip install -i ${PYPI} protobuf==${VERSION} --no-cache-dir) || (retry_pip_install ${PYPI} ${VERSION}) 38} 39 40 41[ $# -lt 1 ] && { 42 echo "Usage: $0 VERSION [" 43 echo "" 44 echo "Examples:" 45 echo " Test 3.3.0 release using version number 3.3.0.dev1:" 46 echo " $0 3.0.0 dev1" 47 echo " Actually release 3.3.0 to PyPI:" 48 echo " $0 3.3.0" 49 exit 1 50} 51VERSION=$1 52DEV=$2 53 54# Make sure we are in a protobuf source tree. 55[ -f "python/google/protobuf/__init__.py" ] || { 56 echo "This script must be ran under root of protobuf source tree." 57 exit 1 58} 59 60# Make sure all files are world-readable. 61find python -type d -exec chmod a+r,a+x {} + 62find python -type f -exec chmod a+r {} + 63umask 0022 64 65# Check that the supplied version number matches what's inside the source code. 66SOURCE_VERSION=`get_source_version` 67 68[ "${VERSION}" == "${SOURCE_VERSION}" -o "${VERSION}.${DEV}" == "${SOURCE_VERSION}" ] || { 69 echo "Version number specified on the command line ${VERSION} doesn't match" 70 echo "the actual version number in the source code: ${SOURCE_VERSION}" 71 exit 1 72} 73 74TESTING_ONLY=1 75TESTING_VERSION=${VERSION}.${DEV} 76if [ -z "${DEV}" ]; then 77 read -p "You are releasing ${VERSION} to PyPI. Are you sure? [y/n]" -r 78 echo 79 if [[ ! $REPLY =~ ^[Yy]$ ]]; then 80 exit 1 81 fi 82 TESTING_ONLY=0 83 TESTING_VERSION=${VERSION} 84else 85 # Use dev version number for testing. 86 sed -i -r "s/__version__ = '.*'/__version__ = '${VERSION}.${DEV}'/" python/google/protobuf/__init__.py 87fi 88 89# Copy LICENSE 90cp LICENSE python/LICENSE 91 92cd python 93 94# Run tests locally. 95python3 setup.py build 96python3 setup.py test 97 98# Deploy source package to testing PyPI 99python3 setup.py sdist 100twine upload --skip-existing -r testpypi -u protobuf-wheel-test dist/* 101 102# Sleep to allow time for distribution to be available on pip. 103sleep 5m 104 105# Test locally. 106run_install_test ${TESTING_VERSION} python3 https://test.pypi.org/simple 107 108# Deploy egg/wheel packages to testing PyPI and test again. 109python3 setup.py clean build bdist_wheel 110twine upload --skip-existing -r testpypi -u protobuf-wheel-test dist/* 111sleep 5m 112run_install_test ${TESTING_VERSION} python3 https://test.pypi.org/simple 113 114echo "All install tests have passed using testing PyPI." 115 116if [ $TESTING_ONLY -eq 0 ]; then 117 read -p "Publish to PyPI? [y/n]" -r 118 echo 119 if [[ ! $REPLY =~ ^[Yy]$ ]]; then 120 exit 1 121 fi 122 echo "Publishing to PyPI..." 123 # Be sure to run build before sdist, because otherwise sdist will not include 124 # well-known types. 125 python3 setup.py clean build sdist 126 twine upload --skip-existing -u protobuf-packages dist/* 127 # Be sure to run clean before bdist_xxx, because otherwise bdist_xxx will 128 # include files you may not want in the package. E.g., if you have built 129 # and tested with --cpp_implemenation, bdist_xxx will include the _message.so 130 # file even when you no longer pass the --cpp_implemenation flag. See: 131 # https://github.com/protocolbuffers/protobuf/issues/3042 132 python3 setup.py clean build bdist_wheel 133 twine upload --skip-existing -u protobuf-packages dist/* 134else 135 # Set the version number back (i.e., remove dev suffix). 136 sed -i -r "s/__version__ = '.*'/__version__ = '${VERSION}'/" google/protobuf/__init__.py 137fi 138