shithub: sox

Download patch

ref: f04d6f6a33a93eb572e97eb143d263d87e9fb3b9
parent: dd9ce81fdc520afbe443e2cf2e9f9e94389718b7
author: Chris Bagwell <chris@cnpbagwell.com>
date: Sat Jan 21 13:04:07 EST 2012

Improvements to release.sh script.

Support release candidates.
Add command line options.
Verify everything is committed to git before releasing.
Support auto-generating change report based on git log
instead of hand typing.

--- a/release.sh
+++ b/release.sh
@@ -1,50 +1,173 @@
 #!/bin/sh
-
-# Automatable release steps.  All are optional but default to enabled.
 #
-# 1. Build source packages.
-# 2. Build Windows packages.
-# 3. Generate announce email from NEWS file.
-# 4. Build HTML and PDF documentation and upload to web site.
-# 5. Create new release directory and upload packages to directory.
+# Before a release:
+# * Update configure.ac to match release #. If this is a release candidate,
+#   add "rcN" to end of version.
+# * Tag files to release using following form: git tag sox-14.4.0rc1
 #
+# Automatable release steps.   Most are optional but default to enabled.
+#
+# 1. Verify master git repo matches local git repo.
+# 2. Build source packages.
+# 3. Build Windows packages.
+# 4. Generate announce email from NEWS file.
+# 5. Build HTML and PDF documentation and upload to web site.
+# 6. Create new release directory and upload packages to directory.
+#
 # After a release:
-# * Need to update sourceforge for recommended package to give to each 
+# * Need to update sourceforge for recommended package to give to each
 #   OS.
 # * send announcement email using Mutt or similar (mutt -H sox-RELEASE.email).
 # * Update front page of web site to point to latest files and give
 #   latest news.
+# * Modify configure.ac, increment version # and put "git" at end of #.
 #
-# TODO: Can't be used for pre-releases right now.
-# TODO: Make sure releases are tagged in cvs/git and no files remain
-# uncommitted to make sure release is reproducable.
 
+usage()
+{
+    cat <<HELP
+Usage: `basename $0` [options] <tag_previous> <tag_current>
+
+<tag_previous> can be special value "initial" when ran for first
+time.
+
+Options:
+  --force       force overwritting an existing release
+  --help        this help message
+  --ignore-local-changes        don't abort on uncommitted local changes
+  --no-build	Skip building executable packages
+  --no-release	Skip releasing files.
+  --no-short-log Put NEWS content into email instead of autogenerate.
+  --remote      git remote where the change should be pushed (default "origin")
+  --user <name> username on $hostname
+HELP
+}
+
 build_files=yes
 update_web=yes
 release_files=yes
+ignore_changes=no
+short_log=yes
+user=$USER
+remote=origin
+module="sox"
+webpath="sourceforge.net/projects/sox/files"
+rcpath=""
+email_list="sox-users@lists.sourceforge.net,sox-devel@lists.sourceforge.net"
+hostname="shell.sourceforge.net"
+release_path="/home/frs/project/s/so/sox"
+release_force="no"
+web_path="/home/project-web/sox/htdocs"
 
+
+while [ $# != 0 ]; do
+    case "$1" in
+    --force)
+        force="yes"
+        shift
+        ;;
+    --help)
+        usage
+        exit 0
+        ;;
+    --ignore-local-changes)
+        ignore_changes=yes
+        shift
+        ;;
+    --no-build)
+	build_files=no
+	shift
+	;;
+    --no-release)
+	release_files=no
+	shift
+	;;
+    --no-short-log)
+	short_log=no
+	shift
+	;;
+    --remote)
+        shift
+        remote=$1
+        shift
+        ;;
+    --user)
+	shift
+	user=$1
+	shift
+	;;
+    --*)
+        echo "error: unknown option"
+        usage
+        exit 1
+        ;;
+    *)
+        tag_previous="$1"
+        tag_current="$2"
+        shift 2
+        if [ $# != 0 ]; then
+            echo "error: unknown parameter"
+            usage
+            exit 1
+        fi
+        ;;
+    esac
+done
+
 # configure must have been ran to get release #.
-[ ! -x configure ] && autoreconf -i 
+[ ! -x configure ] && autoreconf -i
 [ ! -f Makefile ] && ./configure
 
-release_num=`grep Version: sox.pc | cut -d ' ' -f 2`
+# Check if the object has been pushed. Do do so
+# 1. Check if the current branch has the object. If not, abort.
+# 2. Check if the object is on $remote/branchname. If not, abort.
+local_sha=`git rev-list -1 $tag_current`
+current_branch=`git branch | grep "\*" | sed -e "s/\* //"`
+set +e
+git rev-list $current_branch | grep $local_sha > /dev/null
+if [ $? -eq 1 ]; then
+    echo "Cannot find tag '$tag_current' on current branch. Aborting."
+    echo "Switch to the correct branch and re-run the script."
+    exit 1
+fi
 
-osx_zip="sox-${release_num}-macosx.zip"
-win_zip="sox-${release_num}-win32.zip"
-win_exe="sox-${release_num}-win32.exe"
-src_gz="sox-${release_num}.tar.gz"
-src_bz2="sox-${release_num}.tar.bz2"
-release_list="$src_gz $src_bz2 $win_exe $win_zip $osx_zip"
+revs=`git rev-list $remote/$current_branch..$current_branch | wc -l`
+if [ $revs -ne 0 ]; then
+    git rev-list $remote/$current_branch..$current_branch | grep $local_sha > /dev/null
 
-email_list="sox-users@lists.sourceforge.net,sox-devel@lists.sourceforge.net"
-email_file="sox-${release_num}.email"
+    if [ $? -ne 1 ]; then
+        echo "$remote/$current_branch doesn't have object $local_sha"
+        echo "for tag '$tag_current'. Did you push branch first? Aborting."
+        exit 1
+    fi
+fi
+set -e
 
-username="${USER},sox"
-hostname="shell.sourceforge.net"
-release_path="/home/frs/project/s/so/sox/sox"
-release_force="no"
-web_path="/home/project-web/sox/htdocs"
+module="${tag_current%-*}"
+if [ "x$module" = "x$tag_current" ]; then
+    # release-number-only tag.
+    pwd=`pwd`
+    module=`basename $pwd`
+    release_num="$tag_current"
+else
+    # module-and-release-number style tag
+    release_num="${tag_current##*-}"
+fi
 
+detected_module=`grep 'PACKAGE = ' Makefile | sed 's|PACKAGE = ||'`
+if [ -f $detected_module-$release_num.tar.bz2 ]; then
+    module=$detected_module
+fi
+
+osx_zip="$module-${release_num}-macosx.zip"
+win_zip="$module-${release_num}-win32.zip"
+win_exe="$module-${release_num}-win32.exe"
+src_gz="$module-${release_num}.tar.gz"
+src_bz2="$module-${release_num}.tar.bz2"
+release_list="$src_gz $src_bz2 $win_exe $win_zip $osx_zip"
+
+email_file="${module}-${release_num}.email"
+
 build()
 {
     echo "Creating source packages..."
@@ -55,7 +178,7 @@
     make -s distclean
     rm -f $win_zip
     rm -f $win_exe
-    ./mingwbuild 
+    ./mingwbuild
 
     if [ $update_web = "yes" ]; then
 	echo "Creating HTML documentation for web site..."
@@ -66,6 +189,9 @@
     fi
 }
 
+MD5SUM=`which md5sum || which gmd5sum`
+SHA1SUM=`which sha1sum || which gsha1sum`
+
 create_email()
 {
     cat<<EMAIL_HEADER
@@ -74,17 +200,56 @@
 
 EMAIL_HEADER
 
-cat NEWS
+    if [ $short_log = "yes" ]; then
+	case "$tag_previous" in
+	    initial)
+		range="$tag_current"
+		;;
+	    *)
+		range="$tag_previous".."$tag_current"
+		;;
+	esac
+	echo "git tag: $tag_current"
+	echo
+	git log --no-merges "$range" | git shortlog
+    else
+	cat NEWS
+    fi
+
+    cat<<EMAIL_FOOTER
+
+http://$webpath/${rcpath}${module}/$osx_zip/download
+MD5:  `$MD5SUM $osx_zip`
+SHA1: `$SHA1SUM $osx_zip`
+
+http://$webpath/${rcpath}${module}/$win_exe/download
+MD5:  `$MD5SUM $win_exe`
+SHA1: `$SHA1SUM $win_exe`
+
+http://$webpath/${rcpath}${module}/$win_zip/download
+MD5:  `$MD5SUM $win_zip`
+SHA1: `$SHA1SUM $win_zip`
+
+http://$webpath/${rcpath}${module}/$src_bz2/download
+MD5:  `$MD5SUM $src_bz2`
+SHA1: `$SHA1SUM $src_bz2`
+
+http://$webpath/${rcpath}${module}/$src_gz/download
+MD5:  `$MD5SUM $src_gz`
+SHA1: `$SHA1SUM $src_gz`
+
+EMAIL_FOOTER
 }
 
 case $release_num in
-    *cvs|*git)
+    *git)
 	echo "Aborting.  Should not release untracked version number."
 	exit 1
 	;;
-    *rc*)
-	echo "TODO: Upload path for RC's is different.  Aborting."
-	exit 1;
+    *rc?|*rc??)
+	echo "Release candidate detected. Disabling web update."
+	update_web=no
+	rcpath="release_candidates/"
 	;;
 esac
 
@@ -93,9 +258,9 @@
     exit 1
 fi
 
-
 if [ $build_files = "yes" ]; then
     build
+    echo
 fi
 
 if [ ! -f $src_gz -o ! -f $src_bz2 ]; then
@@ -108,12 +273,25 @@
     exit 1
 fi
 
+# Check for uncommitted/queued changes.
+if [ "$ignore_changes" != "yes" ]; then
+    set +e
+    git diff --exit-code > /dev/null 2>&1
+    if [ $? -ne 0 ]; then
+	echo "Uncommitted changes found. Did you forget to commit? Aborting."
+	echo "Use --ignore-local-changes to skip this check."
+	exit 1
+    fi
+    set -e
+fi
+
 create_email > $email_file
 
+username="${user},sox"
+
 if [ $update_web = "yes" -o $release_files = "yes" ]; then
     echo "Creating shell on sourceforge for $username"
-    ssh ${username}@${hostname}  create
-    sleep 30
+    ssh ${username}@${hostname} create
 fi
 
 if [ $update_web = "yes" ]; then
@@ -126,13 +304,13 @@
 
 if [ $release_files = "yes" ]; then
     echo "Checking for an existing release..."
-    if ssh ${username}@${hostname} ls ${release_path}/${release_num}/$src_gz >/dev/null 2>&1; then
+    if ssh ${username}@${hostname} ls ${release_path}/${rcpath}${module}/${release_num}/$src_gz >/dev/null 2>&1; then
 	if [ "$release_force" != "yes" ]; then
 	    echo "error: file already exists!"
 	    exit 1
 	fi
     fi
-    ssh ${username}@${hostname} mkdir -p ${release_path}/${release_num}
-    scp -p $release_list ${username}@${hostname}:${release_path}/${release_num}
-    scp -p NEWS ${username}@${hostname}:${release_path}/${release_num}/README
+    ssh ${username}@${hostname} mkdir -p ${release_path}/${rcpath}${module}/${release_num}
+    scp -p $release_list ${username}@${hostname}:${release_path}/${rcpath}${module}/${release_num}
+    scp -p NEWS ${username}@${hostname}:${release_path}/${rcpath}${module}/${release_num}/README
 fi