xref: /aosp_15_r20/external/protobuf/python/release.sh (revision 1b3f573f81763fcece89efc2b6a5209149e44ab8)
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