/ tools / dev-release.sh
dev-release.sh
  1  #!/bin/sh -xe
  2  # Release dev packages to PyPI
  3  
  4  version="0.0.0.dev$(date +%Y%m%d)"
  5  DEV_RELEASE_BRANCH="dev-release"
  6  # TODO: create a real release key instead of using Kuba's personal one
  7  RELEASE_GPG_KEY="${RELEASE_GPG_KEY:-148C30F6F7E429337A72D992B00B9CC82D7ADF2C}"
  8  
  9  # port for a local Python Package Index (used in testing)
 10  PORT=${PORT:-1234}
 11  
 12  # subpackages to be released
 13  SUBPKGS=${SUBPKGS:-"acme letsencrypt-apache letsencrypt-nginx letshelp-letsencrypt"}
 14  subpkgs_modules="$(echo $SUBPKGS | sed s/-/_/g)"
 15  # letsencrypt_compatibility_test is not packaged because:
 16  # - it is not meant to be used by anyone else than Let's Encrypt devs
 17  # - it causes problems when running nosetests - the latter tries to
 18  #   run everything that matches test*, while there are no unittests
 19  #   there
 20  
 21  tag="v$version"
 22  mv "dist.$version" "dist.$version.$(date +%s).bak" || true
 23  git tag --delete "$tag" || true
 24  
 25  tmpvenv=$(mktemp -d)
 26  virtualenv --no-site-packages $tmpvenv
 27  . $tmpvenv/bin/activate
 28  # update setuptools/pip just like in other places in the repo
 29  pip install -U setuptools
 30  pip install -U pip  # latest pip => no --pre for dev releases
 31  pip install -U wheel  # setup.py bdist_wheel
 32  
 33  # newer versions of virtualenv inherit setuptools/pip/wheel versions
 34  # from current env when creating a child env
 35  pip install -U virtualenv
 36  
 37  root="$(mktemp -d -t le.$version.XXX)"
 38  echo "Cloning into fresh copy at $root"  # clean repo = no artificats
 39  git clone . $root
 40  git rev-parse HEAD
 41  cd $root
 42  git branch -f "$DEV_RELEASE_BRANCH"
 43  git checkout "$DEV_RELEASE_BRANCH"
 44  
 45  for pkg_dir in $SUBPKGS
 46  do
 47    sed -i $x "s/^version.*/version = '$version'/" $pkg_dir/setup.py
 48  done
 49  sed -i "s/^__version.*/__version__ = '$version'/" letsencrypt/__init__.py
 50  
 51  git add -p  # interactive user input
 52  git -c commit.gpgsign=true commit -m "Release $version"
 53  git tag --local-user "$RELEASE_GPG_KEY" \
 54      --sign --message "Release $version" "$tag"
 55  
 56  echo "Preparing sdists and wheels"
 57  for pkg_dir in . $SUBPKGS
 58  do
 59    cd $pkg_dir
 60  
 61    python setup.py clean
 62    rm -rf build dist
 63    python setup.py sdist
 64    python setup.py bdist_wheel
 65  
 66    echo "Signing ($pkg_dir)"
 67    for x in dist/*.tar.gz dist/*.whl
 68    do
 69        gpg2 --detach-sign --armor --sign $x
 70    done
 71  
 72    cd -
 73  done
 74  
 75  mkdir "dist.$version"
 76  mv dist "dist.$version/letsencrypt"
 77  for pkg_dir in $SUBPKGS
 78  do
 79    mv $pkg_dir/dist "dist.$version/$pkg_dir/"
 80  done
 81  
 82  echo "Testing packages"
 83  cd "dist.$version"
 84  # start local PyPI
 85  python -m SimpleHTTPServer $PORT &
 86  # cd .. is NOT done on purpose: we make sure that all subpackages are
 87  # installed from local PyPI rather than current directory (repo root)
 88  virtualenv --no-site-packages ../venv
 89  . ../venv/bin/activate
 90  pip install -U setuptools
 91  pip install -U pip
 92  # Now, use our local PyPI
 93  pip install \
 94    --extra-index-url http://localhost:$PORT \
 95    letsencrypt $SUBPKGS
 96  # stop local PyPI
 97  kill $!
 98  
 99  # freeze before installing anything else, so that we know end-user KGS
100  # make sure "twine upload" doesn't catch "kgs"
101  mkdir ../kgs
102  kgs="../kgs/$version"
103  pip freeze | tee $kgs
104  pip install nose
105  nosetests letsencrypt $subpkgs_modules
106  
107  echo "New root: $root"
108  echo "KGS is at $root/kgs"
109  echo "In order to upload packages run the following command:"
110  echo twine upload "$root/dist.$version/*/*"