release.sh 4.0 KB

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