cannam@48: #! /usr/bin/env bash cannam@48: cannam@48: set -euo pipefail cannam@48: cannam@48: if (grep -r KJ_DBG c++/src | egrep -v '/debug(-test)?[.]'); then cannam@48: echo '*** Error: There are instances of KJ_DBG in the code.' >&2 cannam@48: exit 1 cannam@48: fi cannam@48: cannam@48: if (egrep -r 'TODO\((now|soon)\)' *); then cannam@48: echo '*** Error: There are release-blocking TODOs in the code.' >&2 cannam@48: exit 1 cannam@48: fi cannam@48: cannam@48: doit() { cannam@48: echo "@@@@ $@" cannam@48: "$@" cannam@48: } cannam@48: cannam@48: get_version() { cannam@48: local VERSION=$(grep AC_INIT c++/configure.ac | sed -e 's/^[^]]*],\[\([^]]*\)].*$/\1/g') cannam@48: if [[ ! "$VERSION" =~ $1 ]]; then cannam@48: echo "Couldn't parse version: $VERSION" >&2 cannam@48: exit 1 cannam@48: fi cannam@48: echo "$VERSION" cannam@48: } cannam@48: cannam@48: get_release_version() { cannam@48: get_version '^[0-9]+[.][0-9]+[.][0-9]+(-rc[0-9]+|[.][0-9]+)?$' cannam@48: } cannam@48: cannam@48: update_version() { cannam@48: local OLD=$1 cannam@48: local NEW=$2 cannam@48: local BRANCH_DESC=$3 cannam@48: cannam@48: local OLD_REGEX=${OLD//./[.]} cannam@48: doit sed -i -e "s/$OLD_REGEX/$NEW/g" c++/configure.ac cannam@48: doit sed -i -e "s/set(VERSION.*)/set(VERSION $NEW)/g" c++/CMakeLists.txt cannam@48: cannam@48: local NEW_NOTAG=${NEW%%-*} cannam@48: declare -a NEW_ARR=(${NEW_NOTAG//./ }) cannam@48: doit sed -i -re " cannam@48: s/^#define CAPNP_VERSION_MAJOR [0-9]+\$/#define CAPNP_VERSION_MAJOR ${NEW_ARR[0]}/g; cannam@48: s/^#define CAPNP_VERSION_MINOR [0-9]+\$/#define CAPNP_VERSION_MINOR ${NEW_ARR[1]}/g; cannam@48: s/^#define CAPNP_VERSION_MICRO [0-9]+\$/#define CAPNP_VERSION_MICRO ${NEW_ARR[2]:-0}/g" \ cannam@48: c++/src/capnp/common.h cannam@48: cannam@48: local NEW_COMBINED=$(( ${NEW_ARR[0]} * 1000000 + ${NEW_ARR[1]} * 1000 + ${NEW_ARR[2]:-0 })) cannam@48: doit sed -i -re "s/^#if CAPNP_VERSION != [0-9]*\$/#if CAPNP_VERSION != $NEW_COMBINED/g" \ cannam@48: c++/src/*/*.capnp.h c++/src/*/*/*.capnp.h cannam@48: cannam@48: doit git commit -a -m "Set $BRANCH_DESC version to $NEW." cannam@48: } cannam@48: cannam@48: build_packages() { cannam@48: local VERSION=$1 cannam@48: local VERSION_BASE=${VERSION%%-*} cannam@48: cannam@48: echo "=========================================================================" cannam@48: echo "Building C++ package..." cannam@48: echo "=========================================================================" cannam@48: cd c++ cannam@48: doit autoreconf -i cannam@48: doit ./configure cannam@48: doit make -j6 distcheck cannam@48: doit make dist-zip cannam@48: doit mv capnproto-c++-$VERSION.tar.gz .. cannam@48: doit mv capnproto-c++-$VERSION.zip ../capnproto-c++-win32-$VERSION.zip cannam@48: doit make distclean cannam@48: doit ./configure --host=i686-w64-mingw32 --with-external-capnp \ cannam@48: --disable-shared CXXFLAGS='-static-libgcc -static-libstdc++' cannam@48: doit make -j6 capnp.exe capnpc-c++.exe capnpc-capnp.exe cannam@48: doit i686-w64-mingw32-strip capnp.exe capnpc-c++.exe capnpc-capnp.exe cannam@48: doit mkdir capnproto-tools-win32-$VERSION cannam@48: doit mv capnp.exe capnpc-c++.exe capnpc-capnp.exe capnproto-tools-win32-$VERSION cannam@48: doit zip -r ../capnproto-c++-win32-$VERSION.zip capnproto-tools-win32-$VERSION cannam@48: doit make maintainer-clean cannam@48: cd .. cannam@48: } cannam@48: cannam@48: cherry_pick() { cannam@48: shift cannam@48: if [ $# -gt 0 ]; then cannam@48: echo "=========================================================================" cannam@48: echo "Cherry-picking fixes" cannam@48: echo "=========================================================================" cannam@48: doit git cherry-pick "$@" cannam@48: fi cannam@48: } cannam@48: cannam@48: done_banner() { cannam@48: local VERSION=$1 cannam@48: local PUSH=$2 cannam@48: local FINAL=$3 cannam@48: echo "=========================================================================" cannam@48: echo "Done" cannam@48: echo "=========================================================================" cannam@48: echo "Ready to release:" cannam@48: echo " capnproto-c++-$VERSION.tar.gz" cannam@48: echo " capnproto-c++-win32-$VERSION.zip" cannam@48: echo "Don't forget to push changes:" cannam@48: echo " git push origin $PUSH" cannam@48: cannam@48: read -s -n 1 -p "Shall I push to git and upload to capnproto.org now? (y/N)" YESNO cannam@48: cannam@48: echo cannam@48: case "$YESNO" in cannam@48: y | Y ) cannam@48: doit git push origin $PUSH cannam@48: doit gcutil push fe capnproto-c++-$VERSION.tar.gz capnproto-c++-win32-$VERSION.zip \ cannam@48: /var/www/capnproto.org cannam@48: cannam@48: if [ "$FINAL" = yes ]; then cannam@48: echo "=========================================================================" cannam@48: echo "Publishing docs" cannam@48: echo "=========================================================================" cannam@48: cd doc cannam@48: doit ./push-site.sh cannam@48: cd .. cannam@48: echo "=========================================================================" cannam@48: echo "Really done" cannam@48: echo "=========================================================================" cannam@48: fi cannam@48: cannam@48: echo "Release is available at:" cannam@48: echo " http://capnproto.org/capnproto-c++-$VERSION.tar.gz" cannam@48: ;; cannam@48: * ) cannam@48: echo "OK, do it yourself then." cannam@48: ;; cannam@48: esac cannam@48: } cannam@48: cannam@48: BRANCH=$(git rev-parse --abbrev-ref HEAD) cannam@48: cannam@48: case "${1-}:$BRANCH" in cannam@48: # ====================================================================================== cannam@48: candidate:master ) cannam@48: echo "New major release." cannam@48: cannam@48: if [ $# -gt 1 ]; then cannam@48: echo "Cannot cherry-pick when starting from master. Do it yourself." >&2 cannam@48: exit 1 cannam@48: fi cannam@48: cannam@48: HEAD_VERSION=$(get_version '^[0-9]+[.][0-9]+-dev$') cannam@48: RELEASE_VERSION=${HEAD_VERSION%%-dev}.0 cannam@48: cannam@48: echo "Version: $RELEASE_VERSION" cannam@48: cannam@48: echo "=========================================================================" cannam@48: echo "Creating release branch..." cannam@48: echo "=========================================================================" cannam@48: doit git checkout -b release-$RELEASE_VERSION cannam@48: cannam@48: update_version $HEAD_VERSION $RELEASE_VERSION-rc1 "release branch" cannam@48: cannam@48: build_packages $RELEASE_VERSION-rc1 cannam@48: cannam@48: echo "=========================================================================" cannam@48: echo "Updating version in master branch..." cannam@48: echo "=========================================================================" cannam@48: cannam@48: doit git checkout master cannam@48: declare -a VERSION_ARR=(${RELEASE_VERSION//./ }) cannam@48: NEXT_VERSION=${VERSION_ARR[0]}.$((VERSION_ARR[1] + 1)) cannam@48: cannam@48: update_version $HEAD_VERSION $NEXT_VERSION-dev "mainlaine" cannam@48: cannam@48: done_banner $RELEASE_VERSION-rc1 "master release-$RELEASE_VERSION" no cannam@48: ;; cannam@48: cannam@48: # ====================================================================================== cannam@48: candidate:release-* ) cannam@48: echo "New release candidate." cannam@48: OLD_VERSION=$(get_release_version) cannam@48: cannam@48: if [[ $OLD_VERSION == *-rc* ]]; then cannam@48: # New release candidate for existing release. cannam@48: cannam@48: RC=${OLD_VERSION##*-rc} cannam@48: BRANCH_VERSION=${OLD_VERSION%%-rc*} cannam@48: RC_VERSION=$BRANCH_VERSION-rc$(( RC + 1 )) cannam@48: cannam@48: echo "Version: $RC_VERSION" cannam@48: else cannam@48: # New micro release. cannam@48: cannam@48: declare -a VERSION_ARR=(${OLD_VERSION//./ }) cannam@48: BRANCH_VERSION=${VERSION_ARR[0]}.${VERSION_ARR[1]}.$((VERSION_ARR[2] + 1)) cannam@48: cannam@48: RC_VERSION=$BRANCH_VERSION-rc1 cannam@48: echo "Version: $RC_VERSION" cannam@48: cannam@48: echo "=========================================================================" cannam@48: echo "Creating new release branch..." cannam@48: echo "=========================================================================" cannam@48: cannam@48: doit git checkout -b release-$BRANCH_VERSION cannam@48: fi cannam@48: cannam@48: echo "=========================================================================" cannam@48: echo "Updating version number to $RC_VERSION..." cannam@48: echo "=========================================================================" cannam@48: cannam@48: update_version $OLD_VERSION $RC_VERSION "release branch" cannam@48: cannam@48: cherry_pick "$@" cannam@48: cannam@48: build_packages $RC_VERSION cannam@48: cannam@48: done_banner $RC_VERSION release-$BRANCH_VERSION no cannam@48: ;; cannam@48: cannam@48: # ====================================================================================== cannam@48: final:release-* ) cannam@48: echo "Final release." cannam@48: OLD_VERSION=$(get_release_version) cannam@48: cannam@48: if [[ $OLD_VERSION != *-rc* ]]; then cannam@48: echo "Current version is already a final release. You need to create a new candidate first." >&2 cannam@48: exit 1 cannam@48: fi cannam@48: cannam@48: if [ $# -gt 1 ]; then cannam@48: echo "Cannot cherry-pick into final release. Make another candidate." >&2 cannam@48: exit 1 cannam@48: fi cannam@48: cannam@48: RC=${OLD_VERSION##*-rc} cannam@48: NEW_VERSION=${OLD_VERSION%%-rc*} cannam@48: cannam@48: echo "Version: $NEW_VERSION" cannam@48: cannam@48: echo "=========================================================================" cannam@48: echo "Updating version number to $NEW_VERSION..." cannam@48: echo "=========================================================================" cannam@48: cannam@48: doit sed -i -re "s/capnproto-c[+][+]-[0-9]+[.][0-9]+[.][0-9]+([.][0-9]+)?\>/capnproto-c++-$NEW_VERSION/g" doc/install.md cannam@48: doit sed -i -re "s/capnproto-c[+][+]-win32-[0-9]+[.][0-9]+[.][0-9]+([.][0-9]+)?\>/capnproto-c++-win32-$NEW_VERSION/g" doc/install.md cannam@48: doit sed -i -re "s/capnproto-tools-win32-[0-9]+[.][0-9]+[.][0-9]+([.][0-9]+)?\>/capnproto-tools-win32-$NEW_VERSION/g" doc/install.md cannam@48: update_version $OLD_VERSION $NEW_VERSION "release branch" cannam@48: cannam@48: doit git tag v$NEW_VERSION cannam@48: cannam@48: build_packages $NEW_VERSION cannam@48: cannam@48: done_banner $NEW_VERSION "v$NEW_VERSION release-$NEW_VERSION" yes cannam@48: ;; cannam@48: cannam@48: # ====================================================================================== cannam@48: security:release-* ) cannam@48: echo "Security release." cannam@48: OLD_VERSION=$(get_release_version) cannam@48: cannam@48: if [[ $OLD_VERSION == *-rc* ]]; then cannam@48: echo "Security releases don't have candidates." >&2 cannam@48: exit 1 cannam@48: fi cannam@48: cannam@48: declare -a VERSION_ARR=(${OLD_VERSION//./ } 0) cannam@48: NEW_VERSION=${VERSION_ARR[0]}.${VERSION_ARR[1]}.${VERSION_ARR[2]}.$((VERSION_ARR[3] + 1)) cannam@48: cannam@48: echo "Version: $NEW_VERSION" cannam@48: cannam@48: echo "=========================================================================" cannam@48: echo "Updating version number to $NEW_VERSION..." cannam@48: echo "=========================================================================" cannam@48: cannam@48: doit sed -i -re "s/capnproto-c[+][+]-[0-9]+[.][0-9]+[.][0-9]+([.][0-9]+)?\>/capnproto-c++-$NEW_VERSION/g" doc/install.md cannam@48: doit sed -i -re "s/capnproto-c[+][+]-win32-[0-9]+[.][0-9]+[.][0-9]+([.][0-9]+)?\>/capnproto-c++-win32-$NEW_VERSION/g" doc/install.md cannam@48: doit sed -i -re "s/capnproto-tools-win32-[0-9]+[.][0-9]+[.][0-9]+([.][0-9]+)?\>/capnproto-tools-win32-$NEW_VERSION/g" doc/install.md cannam@48: update_version $OLD_VERSION $NEW_VERSION "release branch" cannam@48: cannam@48: cherry_pick "$@" cannam@48: cannam@48: doit git tag v$NEW_VERSION cannam@48: cannam@48: build_packages $NEW_VERSION cannam@48: cannam@48: done_banner $NEW_VERSION "v$NEW_VERSION release-$NEW_VERSION" yes cannam@48: ;; cannam@48: cannam@48: # ====================================================================================== cannam@48: retry:release-* ) cannam@48: echo "Retrying release." cannam@48: OLD_VERSION=$(get_release_version) cannam@48: echo "Version: $OLD_VERSION" cannam@48: cannam@48: if [[ $OLD_VERSION == *-rc* ]]; then cannam@48: # We can add more cherry-picks when retrying a candidate. cannam@48: cherry_pick "$@" cannam@48: else cannam@48: if [ $# -gt 1 ]; then cannam@48: echo "Cannot cherry-pick into final release. Make another candidate." >&2 cannam@48: exit 1 cannam@48: fi cannam@48: fi cannam@48: cannam@48: OLD_VERSION=$(get_release_version) cannam@48: build_packages $OLD_VERSION cannam@48: cannam@48: if [[ $OLD_VERSION == *-rc* ]]; then cannam@48: BRANCH_VERSION=${OLD_VERSION%%-rc*} cannam@48: done_banner $OLD_VERSION release-$BRANCH_VERSION no cannam@48: else cannam@48: doit git tag v$OLD_VERSION cannam@48: done_banner $OLD_VERSION "v$OLD_VERSION release-$OLD_VERSION" no cannam@48: fi cannam@48: ;; cannam@48: cannam@48: # ====================================================================================== cannam@48: *:master ) cannam@48: echo "Invalid command for mainline branch. Only command is 'candidate'." >&2 cannam@48: exit 1 cannam@48: ;; cannam@48: cannam@48: *:release-* ) cannam@48: echo "Invalid command for release branch. Commands are 'candidate', 'final', and 'retry'." >&2 cannam@48: exit 1 cannam@48: ;; cannam@48: cannam@48: * ) cannam@48: echo "Not a master or release branch." >&2 cannam@48: exit 1 cannam@48: ;; cannam@48: esac