* Remove Scala 2.11 from crossScalaVersions * because +buildRelease doesn't work with mixed crossScalaVersions * let's use akka.build.scalaVersion when building for 2.11 * aggregatedProjects adjusted depending on akka.build.scalaVersion is 2.11 or not, there excluding/including the -typed modules * update travis to use akka.build.scalaVersion
397 lines
12 KiB
Bash
Executable file
397 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 gustav.akka.io
|
|
# Please note that gustav.akka.io is the same as repo.akka.io,
|
|
# but the latter domain is pointed at cloudflare so one could not ssh into it.
|
|
#
|
|
# 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@gustav.akka.io "cat >> ~/.ssh/authorized_keys"
|
|
##
|
|
# 4) 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@gustav.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=`java -version 2>&1 | grep -E "java version|openjdk version" | cut -d '"' -f2 | cut -d '.' -f1`
|
|
|
|
[[ $JAVA_VERSION -ge 11 ]] || fail "Java version is not at least 11"
|
|
|
|
# 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 | grep -v "coordinated shutdown" | 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} on branch $initial_branch"
|
|
|
|
if [ "${current_version:0:3}" != "${version:0:3}" ]; then
|
|
fail "Releasing $version from wrong branch $initial_branch with version $current_version"
|
|
fi
|
|
|
|
# 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
|
|
try sbt -Dakka.build.scalaVersion=2.11.12 -D$RELEASE_OPT buildRelease
|
|
try sbt $RELEASE_OPT buildDocs
|
|
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
|
|
|
|
try sbt whitesourceCheckPolicies
|
|
|
|
# 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
|
|
|
|
echolog "Uploading whitesource report"
|
|
if [ $dry_run ]; then
|
|
echodry "Not actually uploading whitesource report. Commands:"
|
|
echodry " sbt whitesourceUpdate"
|
|
else
|
|
important sbt whitesourceUpdate
|
|
fi
|
|
|
|
# push the release to the server
|
|
echolog "Pushing ${release_dir} to ${publish_path} ..."
|
|
if [ $dry_run ]; then
|
|
echodry "Not actually pushing to server. Commands:"
|
|
echodry " sbt deployRsync"
|
|
echodry " rsync -rlpvz --chmod=Dg+ws,Fg+w --exclude ${release_dir}/downloads --exclude ${release_dir}/docs ${release_dir}/ ${publish_path}/"
|
|
else
|
|
important ssh ${release_server} "cd ${release_path}/docs/akka; git add .; git commit -m 'before publishing version $version'; true"
|
|
important sbt "deployRsync ${release_server}"
|
|
important rsync -rlpvz --chmod=Dg+ws,Fg+w --exclude downloads --exclude docs ${release_dir}/ ${publish_path}/
|
|
#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
|