pekko/project/scripts/release

283 lines
7.4 KiB
Text
Raw Normal View History

2011-12-09 21:55:49 +13:00
#!/usr/bin/env bash
#
# Release script for Akka.
#
# To run this script you need a user account on akka.io and contributor access
2012-03-05 23:09:06 +01:00
# to github.com/akka/akka.
#
# If your username on akka.io is different from your local username then you can
# configure ssh to always associate a particular username with akka.io by adding
# the following to .ssh/config:
# Host akka.io
# User <username on akka.io>
2011-12-09 21:55:49 +13:00
# defaults
declare -r default_server="akka.io"
declare -r default_path="/akka/www"
# settings
declare -r release_dir="target/release"
declare release_server=${default_server}
declare release_path=${default_path}
declare -r unzipped_dir="target/dist/unzipped"
2011-12-09 21:55:49 +13:00
# flags
unset run_tests dry_run
2011-12-09 21:55:49 +13:00
# get the source location for this script; handles symlinks
function get_script_path {
local source="${BASH_SOURCE[0]}"
while [ -h "${source}" ] ; do
source="$(readlink "${source}")";
done
echo ${source}
}
# path, name, and dir for this script
declare -r script_path=$(get_script_path)
declare -r script_name=$(basename "${script_path}")
declare -r script_dir="$(cd -P "$(dirname "${script_path}")" && pwd)"
# print usage info
function usage {
cat <<EOM
Usage: ${script_name} [options] VERSION
-h | --help Print this usage message
-t | --run-tests Run all tests before releasing
-s | --server SERVER Set the release server (default ${default_server})
-p | --path PATH Set the path on the release server (default ${default_path})
-n | --dry-run Build everything but do not push the release
2011-12-09 21:55:49 +13:00
EOM
}
# echo a log message
function echolog {
echo "[${script_name}] $@"
}
# echo an error message
function echoerr {
echo "[${script_name}] $@" 1>&2
}
# echo a dry run log message
function echodry {
echolog "(dry run) $@"
}
2011-12-09 21:55:49 +13:00
# fail the script with an error message
function fail {
echoerr "$@"
exit 1
}
# process options and set flags
while true; do
case "$1" in
-h | --help ) usage; exit 1 ;;
-t | --run-tests ) run_tests=true; shift ;;
-s | --server ) release_server=$2; shift 2 ;;
-p | --path ) release_path=$2; shift 2 ;;
-n | --dry-run) dry_run=true; shift ;;
2011-12-09 21:55:49 +13:00
* ) break ;;
esac
done
if [ $# != "1" ]; then
usage
fail "A release version must be specified"
fi
declare -r version=$1
declare -r publish_path="${release_server}:${release_path}"
# check for a git command
type -P git &> /dev/null || fail "git command not found"
# check for an sbt command
type -P sbt &> /dev/null || fail "sbt command not found"
# check for an rsync command
type -P rsync &> /dev/null || fail "rsync command not found"
# check for a tar command
type -P tar &> /dev/null || fail "tar command not found"
2011-12-09 21:55:49 +13:00
# get the current git branch
function get_current_branch {
local ref=$(git symbolic-ref HEAD 2> /dev/null)
local branch=${ref#refs/heads/}
echo "${branch}"
}
# get the current project version from sbt
# a little messy as the ansi escape codes are included
function get_current_version {
local result=$(sbt version | tail -1 | cut -f2)
# remove ansi escape code from end
local code0=$(echo -e "\033[0m")
echo ${result%$code0}
}
# store the current git branch for cleaning up
declare -r initial_branch=$(get_current_branch)
# check we have an initial branch
[[ "${initial_branch}" ]] || fail "Not on a git branch"
# check that we have a clean status
[[ -z "$(git status --porcelain)" ]] || {
git status
fail "There are uncommitted changes - please commit before releasing"
}
# the branch we'll release on
declare -r release_branch="releasing-${version}"
# try to run a cleanup command - these shouldn't actually fail
function safely {
"$@" || fail "Failed to clean up release - please check current state"
}
# perform a clean up when a failure has occurred
function git_cleanup {
echoerr "Cleaning up..."
local branch=$(get_current_branch)
safely git reset --hard
safely git clean -f
if [ "${branch}" == "${release_branch}" ]; then
safely git checkout ${initial_branch}
safely git branch -D ${release_branch}
2011-12-09 21:55:49 +13:00
local tags=$(git tag -l)
[[ "${tags}" == *v${version}* ]] && safely git tag -d v${version}
fi
}
# clean up and fail the script with an error message
function bail_out {
echoerr "Bailing out!"
git_cleanup
echoerr "Cleaned up failed release"
2011-12-09 21:55:49 +13:00
fail "$@"
}
# bail out for signals
function signal_bail_out {
echoerr "Interrupted by signal"
bail_out "Received signal to stop release"
}
# bail out on signals
trap signal_bail_out SIGHUP SIGINT SIGTERM
# try to run a command or otherwise bail out
function try {
"$@" || bail_out "Failed to create release"
}
echolog "Creating release ${version} ..."
if [ $dry_run ]; then
echodry "Building everything but not pushing release"
else
echolog "Publishing to ${publish_path}"
fi
2011-12-09 21:55:49 +13:00
[[ $run_tests ]] && echolog "All tests will be run"
# try ssh'ing to the release server
echolog "Checking ssh connection to ${release_server}"
try ssh -t ${release_server} echo "Successfully contacted release server."
echolog "Getting current project version from sbt..."
declare -r current_version=$(get_current_version)
echolog "Current version is ${current_version}"
# check out a release branch
try git checkout -b ${release_branch}
# find and replace the version
try ${script_dir}/find-replace ${current_version} ${version}
# start clean
try sbt clean
# run the tests if specified
if [ $run_tests ]; then
echolog "Running all tests..."
try sbt test
echolog "All tests are green"
fi
# build the release
echolog "Building the release..."
try sbt build-release
2011-12-12 15:45:43 +13:00
try cp akka-spring/src/main/resources/akka/spring/akka-*.xsd ${release_dir}
echolog "Creating gzipped tar download..."
try tar -cz -C ${unzipped_dir} -f ${release_dir}/downloads/akka-${version}.tgz akka-${version}
2011-12-09 21:55:49 +13:00
echolog "Successfully created local release"
# commit and tag this release
echolog "Committing and tagging..."
try git add .
try git commit -am "Update version for release ${version}"
try git tag -m "Version ${version}" v${version}
# the point of no return... we're now pushing out to servers
# use a special failure from now on
function arrgh {
cat 1>&2 <<EOM
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Release failed while pushing to servers!
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
EOM
fail "Could not complete release - please check current state"
}
# try running a pushing command or otherwise fail
function important {
"$@" || arrgh
}
# new interrupted bail out for signals
function arrgh_interrupt {
echoerr "Interrupted by signal"
arrgh
}
# new exit on signals
trap arrgh_interrupt SIGHUP SIGINT SIGTERM
# push the commits and tags to git origin
echolog "Pushing to git origin..."
if [ $dry_run ]; then
echodry "Not actually pushing to git origin. Commands:"
echodry " git push origin ${release_branch}"
echodry " git push origin --tags"
else
important git push origin ${release_branch}
important git push origin --tags
fi
2011-12-09 21:55:49 +13:00
# push the release to the server
echolog "Pushing ${release_dir} to ${publish_path} ..."
if [ $dry_run ]; then
echodry "Not actually pushing to server. Command:"
echodry " rsync -rlpvz --chmod=Dg+ws,Fg+w ${release_dir}/ ${publish_path}/"
else
important rsync -rlpvz --chmod=Dg+ws,Fg+w ${release_dir}/ ${publish_path}/
fi
2011-12-09 21:55:49 +13:00
if [ $dry_run ]; then
git_cleanup
echodry "Successfully created release ${version}"
echodry "See ${release_dir}"
else
echolog "Switching back to initial branch"
git checkout ${initial_branch}
echolog "Successfully created release ${version}"
fi