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