This will also git commit before and after the upload of the docs, so as to make sure that changes to warnOldDocs.js are recoverable.
387 lines
12 KiB
Bash
Executable file
387 lines
12 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
#
|
|
# Release script for Akka.
|
|
#
|
|
# ATTENTION: This script involves calling `git clean -fxd` which will remove all untracked
|
|
# files from your working directory (including IDE settings).
|
|
#
|
|
# Prerequisites and Installation Instructions
|
|
#
|
|
# 1) You must be able to sign the artifacts with PGP
|
|
#
|
|
# 1.1) If you don't have PGP and a PGP key
|
|
# On OS X from othe command line:
|
|
# shell> brew install gnupg
|
|
# shell> gpg --gen-key
|
|
#
|
|
# Default values for the key type and 2048 bits is OK.
|
|
# Make sure to use the email address that you will use later to register
|
|
# with Sonatype.
|
|
#
|
|
# 1.2) Check that signing works
|
|
# From inside sbt do the following
|
|
# sbt> publishLocalSigned
|
|
# It should should ask you for your pass phrase, and create .asc files for
|
|
# all artifacts
|
|
#
|
|
# 1.3) Publish your key to a server that Sonatype use
|
|
# From the command line:
|
|
# shell> gpg --keyserver hkp://pool.sks-keyservers.net/ --send-keys <your key id>
|
|
# To find out your key id do this from the command line:
|
|
# shell> gpg --list-keys
|
|
# pub 2048/<your key id> ...
|
|
# You can verify the existence of your key here, if you don't trust your tool:
|
|
# https://sks-keyservers.net/i/#extract
|
|
#
|
|
# 2) You must have publishing rights to oss.sonatype.org
|
|
#
|
|
# 2.1) Register with oss.sonatype.org by only following the instructions under
|
|
# sign up here https://docs.sonatype.org/display/Repository/Sonatype+OSS+Maven+Repository+Usage+Guide
|
|
# Use the same email address as you used for the pgp key.
|
|
#
|
|
# 2.2) Ask Jonas who is the original creator of this ticket https://issues.sonatype.org/browse/OSSRH-3097
|
|
# to add a comment that says that your username (not your full name) should
|
|
# have publish access to that project. There is manual administration of
|
|
# the ticket at Sonatype, so it could take a little while.
|
|
#
|
|
# 2.3) Add your credentials to sbt by adding a global.sbt file in your sbt home
|
|
# directory containing the following.
|
|
# credentials += Credentials("Sonatype Nexus Repository Manager",
|
|
# "oss.sonatype.org",
|
|
# "<your username>",
|
|
# "<your password>")
|
|
#
|
|
# 3) You must have access to repo.akka.io
|
|
#
|
|
# 3.1) Ask someone in the team for login information for the akkarepo user.
|
|
#
|
|
# 3.2) Install your public ssh key to avoid typing in your password.
|
|
# From the command line:
|
|
# shell> cat ~/.ssh/id_rsa.pub | ssh akkarepo@repo.akka.io "cat >> ~/.ssh/authorized_keys"
|
|
#
|
|
# 4) You must have upload access to S3 bucket "downloads.typesafe.com"
|
|
#
|
|
# 4.1) Ask Akka team member for the AWS access key for 'akka.team' user.
|
|
#
|
|
# 4.2) Add your credentials to sbt by adding this to your global.sbt file
|
|
# credentials += Credentials("Amazon S3",
|
|
# "downloads.typesafe.com.s3.amazonaws.com",
|
|
# "<Access Key Id>",
|
|
# "<Secret Access Key>")
|
|
#
|
|
# 5) Have access to github.com/akka/akka. This should be a given.
|
|
#
|
|
# Now you should be all set to run the script
|
|
#
|
|
# Run the script in two stages.
|
|
# First a dry run:
|
|
# shell> project/scripts/release <version>
|
|
# And if all goes well a real run:
|
|
# shell> project/scripts/release --real-run <version>
|
|
#
|
|
# The artifacts published to oss.sonatype.org needs to be released by following the
|
|
# instructions under release here
|
|
# https://docs.sonatype.org/display/Repository/Sonatype+OSS+Maven+Repository+Usage+Guide
|
|
|
|
# defaults
|
|
declare -r default_server="akkarepo@repo.akka.io"
|
|
declare -r default_path="www"
|
|
|
|
# settings
|
|
declare -r release_dir="target/release"
|
|
declare release_server=${default_server}
|
|
declare release_path=${default_path}
|
|
|
|
# flags
|
|
unset run_tests dry_run no_mima no_revert
|
|
|
|
# dry-run is the default
|
|
dry_run=true
|
|
|
|
# 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
|
|
Dry run is be default.
|
|
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})
|
|
-e | --real-run Build everything and push the release
|
|
-m | --no-mima Skip binary compatibility check in dry-run
|
|
-r | --no-revert On dry-run don't revert git commits and tags
|
|
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) $@"
|
|
}
|
|
|
|
# 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 ;;
|
|
-e | --real-run) unset dry_run; shift ;;
|
|
-m | --no-mima) no_mima=true; shift ;;
|
|
-r | --no-revert) no_revert=true; shift ;;
|
|
* ) 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}"
|
|
|
|
[[ `java -version 2>&1 | grep -E "java version|openjdk version" | cut -d ' ' -f3 | cut -d '.' -f2` -eq 8 ]] || fail "Java version is not 1.8"
|
|
|
|
# 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"
|
|
|
|
# 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 | grep -v warn | 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"
|
|
}
|
|
|
|
(read -p "The working directory will now be cleaned from all non-tracked files. Are you sure you want this? " x; test "$x" = yes) || fail "bailing out"
|
|
git clean -fxd || fail "cannot git clean -fxd"
|
|
|
|
# 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}
|
|
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"
|
|
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
|
|
|
|
[[ $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..."
|
|
if [ ! $dry_run ]; then
|
|
RELEASE_OPT="-Dakka.genjavadoc.enabled=true -Dpublish.maven.central=true"
|
|
else
|
|
RELEASE_OPT="-Dakka.genjavadoc.enabled=true"
|
|
fi
|
|
try sbt $RELEASE_OPT +buildRelease
|
|
echolog "Successfully created local release"
|
|
|
|
# check binary compatibility for dry run
|
|
if [ ! $no_mima ] && [ $dry_run ]; then
|
|
echodry "Running migration manager report..."
|
|
sbt mimaReportBinaryIssues
|
|
echodry "Finished migration manager report"
|
|
fi
|
|
|
|
# commit and tag this release
|
|
echolog "Committing and tagging..."
|
|
try git add .
|
|
try git commit -am "Update version for release ${version}"
|
|
try git tag -am "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 --tags"
|
|
else
|
|
important git push origin --tags
|
|
fi
|
|
|
|
# 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 --exclude ${release_dir}/downloads ${release_dir}/ ${publish_path}/"
|
|
echodry " sbt uploadRelease"
|
|
else
|
|
important ssh ${release_server} "cd ${release_path}/docs/akka; git add .; git commit -m 'before publishing version $version'; true"
|
|
important rsync -rlpvz --chmod=Dg+ws,Fg+w --exclude ${release_dir}/downloads ${release_dir}/ ${publish_path}/
|
|
important sbt uploadRelease
|
|
important ssh ${release_server} cp -v ${release_path}/docs/akka/${version}/_static/warnOldDocs.js ${release_path}/docs/akka
|
|
important ssh ${release_server} ln -snvf ../../warnOldDocs.js ${release_path}/docs/akka/${version}/_static/warnOldDocs.js
|
|
important ssh ${release_server} "cd ${release_path}/docs/akka; git add .; git commit -m 'publish version $version'"
|
|
fi
|
|
|
|
echolog "*****"
|
|
echolog "Do not forget to update versions.json on akka.github.com!"
|
|
echolog "*****"
|
|
|
|
if [ $dry_run ]; then
|
|
if [ $no_revert ]; then
|
|
echodry "No revert: git branch ${release_branch} and git tag v${version} remain"
|
|
else
|
|
git_cleanup
|
|
fi
|
|
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
|