mirror of https://github.com/sbt/sbt.git
commit
3133ef4506
|
|
@ -0,0 +1,319 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
#
|
||||
# This script will upload an sbt distribution (tar/tgz/msi and
|
||||
# checksump files) to IBM Cloud Object Storage with the correct
|
||||
# permissions, and prepare the shortened URLs on the "piccolo.link"
|
||||
# Polr server.
|
||||
#
|
||||
|
||||
#
|
||||
# Required env vars:
|
||||
#
|
||||
# SBT_DEPLOY_S3KEY -- API Key for the sbt-distribution-archive bucket
|
||||
# SBT_DEPLOY_S3SECRET -- Secret corresponding to the API Key
|
||||
#
|
||||
# POLR_USERNAME -- Username for the polr shortener
|
||||
# POLR_PASSWORD -- Password for the polr shortener
|
||||
#
|
||||
# These environment vars can be either defined by the caller, or directly
|
||||
# in the following lines, in place of the "your..." constants below.
|
||||
#
|
||||
SBT_DEPLOY_S3KEY="${SBT_DEPLOY_S3KEY:-yourSbtDeployS3key}"
|
||||
SBT_DEPLOY_S3SECRET="${SBT_DEPLOY_S3SECRET:-yourSbtDeployS3secret}"
|
||||
POLR_USERNAME="${POLR_USERNAME:-yourPolrUsername}"
|
||||
POLR_PASSWORD="${POLR_PASSWORD:-yourPolrPassword}"
|
||||
|
||||
# Where to find the above information:
|
||||
# - for SBT_DEPLOY_S3KEY/SBT_DEPLOY_S3SECRET, you need the API credentials for the
|
||||
# 'sbt-downloads' buckets on IBM's COS. Please ask @cunei for
|
||||
# details.
|
||||
#
|
||||
# Once you have SBT_DEPLOY_S3KEY/SBT_DEPLOY_S3SECRET, you can (and should) use those
|
||||
# values also in your favorite S3 GUI browser (like CyberDuck
|
||||
# or DragonDisk), in order to verify that the files are correctly
|
||||
# uploaded, or to perform maintenance within the storage bucket.
|
||||
#
|
||||
# Note: do *not* use an S3 GUI to upload files, since that will set
|
||||
# the permissions incorrectly, and the CDN will be unable to access
|
||||
# the files.
|
||||
#
|
||||
# - for POLR_USERNAME/POLR_PASSWORD, you will need the credentials
|
||||
# on "piccolo.link" for the user "lightbend-tools". Ask @cunei
|
||||
# for details. Note: do not create a personal account to generate
|
||||
# the short URLs: they are linked to the user that creates them
|
||||
# and they would not appear in the "lightbend-tools" dashboard.
|
||||
#
|
||||
|
||||
# Once you have set correctly the four vars above, please call
|
||||
# this script as follows:
|
||||
#
|
||||
# If your files have this directory structure:
|
||||
#
|
||||
# here
|
||||
# here/v0.13.15
|
||||
# here/v0.13.15/sbt-0.13.15.msi
|
||||
# here/v0.13.15/sbt-0.13.15.zip.asc
|
||||
# here/v0.13.15/sbt-0.13.15.tgz.asc
|
||||
# here/v0.13.15/sbt-0.13.15.tgz
|
||||
# here/v0.13.15/sbt-0.13.15.zip
|
||||
# here/v0.13.15/sbt-0.13.15.msi.asc
|
||||
#
|
||||
#
|
||||
# then "cd here", then:
|
||||
#
|
||||
# $ .../sbt-upload.sh v0.13.15 [v0.13.16 ...]
|
||||
#
|
||||
# Where one or more directories are specified. Each directory name
|
||||
# must be the letter 'v' plus a release version. The files within
|
||||
# each directory can be named arbitrarily, and live in any
|
||||
# subdirectory.
|
||||
#
|
||||
# Please note that the script will try to store temporary cookies
|
||||
# and other info in a directory called "cookies", which will be
|
||||
# created in the same directory as this script.
|
||||
#
|
||||
#--------------------------------------------------------------
|
||||
#
|
||||
set -o pipefail
|
||||
|
||||
SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
|
||||
usageAndExit() {
|
||||
echo 'Usage: "'${0##*/}' <RELEASEDIR> [<RELEASEDIR> ...]"'
|
||||
echo "where the final path component of each RELEASEDIR"
|
||||
echo "must be 'v' plus"' a release number, for example: "v0.13.15".'
|
||||
echo 'This script will leave some cookie files in a directory'
|
||||
echo 'called "cookies", in the same location as the script.'
|
||||
exit 1
|
||||
}
|
||||
|
||||
|
||||
if [[ "$#" < 1 ]]
|
||||
then
|
||||
usageAndExit
|
||||
fi
|
||||
RELEASE_DIRS=("${@:1}")
|
||||
for RELEASE_DIR in "${RELEASE_DIRS[@]}"
|
||||
do
|
||||
RELEASE_TAG="$(basename "$RELEASE_DIR")"
|
||||
if [[ "${RELEASE_TAG:0:1}" != 'v' || ! -d "${RELEASE_DIR}" ]]
|
||||
then
|
||||
usageAndExit
|
||||
fi
|
||||
done
|
||||
|
||||
|
||||
POLR_DOMAIN_NAME="${POLR_DOMAIN_NAME:-piccolo.link}"
|
||||
POLR_URL="https://$POLR_DOMAIN_NAME"
|
||||
POLR_LOGIN_URL="$POLR_URL/login"
|
||||
POLR_SHORTEN_URL="$POLR_URL/shorten"
|
||||
|
||||
# Let's try to login into Polr
|
||||
|
||||
# Prepare a work directory to store the cookies into
|
||||
COOKIEDIR="${SCRIPTDIR}/cookies"
|
||||
mkdir -p "${COOKIEDIR}"
|
||||
HOME_COOKIES_PATH="${COOKIEDIR}/home-cookies"
|
||||
LOGIN_COOKIES_PATH="${COOKIEDIR}/login-cookies"
|
||||
CSRF_TOKEN_PATH="${COOKIEDIR}/csrf-token"
|
||||
|
||||
# Access home page to get tokens.
|
||||
RESPONSE="$(
|
||||
curl -si "$POLR_URL" \
|
||||
--cookie-jar "$HOME_COOKIES_PATH"
|
||||
)"
|
||||
CODE="$(echo "$RESPONSE" | head -1 | awk '{print $2}')"
|
||||
if [ -z "$CODE" -o "$CODE" -ne 200 ]
|
||||
then
|
||||
echo "ERROR: Could not load $POLR_URL; aborting."
|
||||
echo -e "Response:\n$RESPONSE"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
TOKEN="$(echo "$RESPONSE" | grep "_token" | \
|
||||
sed -E "s/.+value='([a-zA-Z0-9]+)'.+/\1/")"
|
||||
if [ -z "$TOKEN" ]
|
||||
then
|
||||
echo "ERROR: Could not find auth token; aborting."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Save CSRF token.
|
||||
CSRF_TOKEN="$(echo "$RESPONSE" | grep "csrf-token" | \
|
||||
sed -E 's/.+content="([a-zA-Z0-9]+)".+/\1/')"
|
||||
if [ -z "$CSRF_TOKEN" ]
|
||||
then
|
||||
echo "ERROR: Could not find CSRF token; aborting."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "$CSRF_TOKEN" > "$CSRF_TOKEN_PATH"
|
||||
|
||||
# Login and save cookie.
|
||||
RESPONSE="$(
|
||||
curl -siX POST "$POLR_LOGIN_URL" \
|
||||
--cookie "$HOME_COOKIES_PATH" \
|
||||
--cookie-jar "$LOGIN_COOKIES_PATH" \
|
||||
-d "username=$POLR_USERNAME" \
|
||||
-d "password=$POLR_PASSWORD" \
|
||||
-d "_token=$TOKEN" \
|
||||
-d "login='Sign In'"
|
||||
)"
|
||||
CODE="$(echo "$RESPONSE" | head -1 | awk '{print $2}')"
|
||||
if [ -z "$CODE" -o "$CODE" -ne 302 ]
|
||||
then
|
||||
echo "ERROR: Login failed; aborting."
|
||||
echo -e "Response:\n$RESPONSE"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
#
|
||||
# OK! Now, let's process the files
|
||||
#
|
||||
|
||||
#
|
||||
# Call this upload routine with:
|
||||
# 1) relative path to the file from current dir. Do NOT use '..' or '.' in this path
|
||||
# for example: uploadS3 "v1.1.4/sbt-1.1.4.tgz"
|
||||
# assuming the file is in <current dir>/v1.1.4/sbt-1.1.4.tgz
|
||||
#
|
||||
# The file will be placed in the appropriate S3 bucket, and will be visible
|
||||
# as: https://sbt-downloads.cdnedge.bluemix.net/releases/v1.1.4/sbt-1.1.4.tgz
|
||||
#
|
||||
uploadS3() {
|
||||
S3FILEPATH="$1"
|
||||
if [[ -z "$S3FILEPATH" ]]
|
||||
then
|
||||
echo "Internal error! Please report."
|
||||
return 1
|
||||
fi
|
||||
S3BUCKET="sbt-distribution-archives"
|
||||
S3HOST="s3-api.us-geo.objectstorage.softlayer.net"
|
||||
S3RELATIVEPATH="/${S3BUCKET}/releases/${S3FILEPATH}"
|
||||
S3CONTENTTYPE="$(file --brief --mime-type "$S3FILEPATH")"
|
||||
S3NOWDATE="$(date -R)"
|
||||
S3STRINGTOSIGN="PUT\n\n${S3CONTENTTYPE}\n${S3NOWDATE}\nx-amz-acl:public-read\n${S3RELATIVEPATH}"
|
||||
S3SIGNATURE="$(echo -en ${S3STRINGTOSIGN} | openssl sha1 -hmac ${SBT_DEPLOY_S3SECRET} -binary | base64)"
|
||||
echo "Uploading $S3FILEPATH"
|
||||
curl -X PUT -T "${S3FILEPATH}" \
|
||||
-H "Host: ${S3HOST}" \
|
||||
-H "Date: ${S3NOWDATE}" \
|
||||
-H "Content-Type: ${S3CONTENTTYPE}" \
|
||||
-H "x-amz-acl: public-read" \
|
||||
-H "Authorization: AWS ${SBT_DEPLOY_S3KEY}:${S3SIGNATURE}" \
|
||||
"https://${S3HOST}${S3RELATIVEPATH}"
|
||||
if [ $? -ne 0 ]
|
||||
then
|
||||
echo "Sorry, could not upload this file."
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
shorten() {
|
||||
# Arguments
|
||||
URL="$1"
|
||||
ENDING="$2"
|
||||
TAGS=("${@:3}")
|
||||
|
||||
# echo "Short requested: ${ENDING} -- tags: ${TAGS[@]}"
|
||||
# Retrieve the CSRF token
|
||||
# CSRF_TOKEN="$(cat "$CSRF_TOKEN_PATH")"
|
||||
|
||||
TAG_LIST=""
|
||||
if [ "${#TAGS[@]}" -gt 0 ]; then
|
||||
for TAG in "${TAGS[@]}"; do # tag_list%5B%5D=$TAG
|
||||
TAG_LIST="$TAG_LIST -d tag_list[]=$TAG"
|
||||
done
|
||||
fi
|
||||
|
||||
RESPONSE="$(
|
||||
curl -siX POST "$POLR_SHORTEN_URL" \
|
||||
--cookie "$LOGIN_COOKIES_PATH" \
|
||||
-H "X-CSRF-TOKEN: $CSRF_TOKEN" \
|
||||
--data-urlencode "link-url=$URL" \
|
||||
-d "custom-ending=$ENDING" \
|
||||
$TAG_LIST
|
||||
)"
|
||||
|
||||
CODE="$(echo "$RESPONSE" | head -n 1 | awk '{print $2}')"
|
||||
if [ "$CODE" -ne 200 ]
|
||||
then
|
||||
echo "Could not shorten to: '$ENDING', creating a different link."
|
||||
return 1
|
||||
fi
|
||||
|
||||
SHORT_URL="$(
|
||||
echo "$RESPONSE" | \
|
||||
egrep "value='http[s]?://$POLR_DOMAIN_NAME/" | \
|
||||
sed -E "s@.+value='(http[s]?://$POLR_DOMAIN_NAME/[-_\.0-9a-zA-Z]+)'.+@\1@"
|
||||
)"
|
||||
|
||||
echo "--> $SHORT_URL" | sed 's@http://@https://@'
|
||||
}
|
||||
|
||||
for RELEASE_DIR in "${RELEASE_DIRS[@]}"
|
||||
do
|
||||
RELEASE_TAG="$(basename "$RELEASE_DIR")"
|
||||
cd "$(dirname "$RELEASE_DIR")"
|
||||
find "$RELEASE_TAG" -type f -print | while read
|
||||
do
|
||||
echo
|
||||
uploadS3 "$REPLY"
|
||||
if [ $? -eq 0 ]
|
||||
then
|
||||
URL="https://sbt-downloads.cdnedge.bluemix.net/releases/${REPLY}"
|
||||
echo "--> $URL"
|
||||
#
|
||||
# let's calculate the Polr tags.
|
||||
#
|
||||
# In Polr the tags can only be combined with 'or', therefore
|
||||
# we need to subdivide them according to the combinations that
|
||||
# might be needed.
|
||||
#
|
||||
# We add these tags:
|
||||
# - if it is an 'asc' checksum file, "${TAG}_asc", "asc"
|
||||
# - if it is a tar/tgz/tar.gz/txz/tar.xz/zip/msi/deb/rpm/dmg, "${TAG}_bin", "bin"
|
||||
# - if it is another file, "${TAG}_other", "other"
|
||||
# In any case, we add "${TAG}"
|
||||
#
|
||||
# so that:
|
||||
# 1) "${TAG}_asc" + "${TAG}_bin" + "${TAG}_other" are the statistics
|
||||
# for the entire "${TAG}" release
|
||||
# 2) "bin" are all of the archives downloads
|
||||
# 3) "bin" + "asc" + "other" are all of the downloads
|
||||
#
|
||||
if [[ "${REPLY}" == *.asc ]]
|
||||
then
|
||||
KIND="asc"
|
||||
elif [[ "${REPLY}" == *.tar || \
|
||||
"${REPLY}" == *.tgz || \
|
||||
"${REPLY}" == *.tar.gz || \
|
||||
"${REPLY}" == *.txz || \
|
||||
"${REPLY}" == *.tar.xz || \
|
||||
"${REPLY}" == *.zip || \
|
||||
"${REPLY}" == *.msi || \
|
||||
"${REPLY}" == *.deb || \
|
||||
"${REPLY}" == *.rpm || \
|
||||
"${REPLY}" == *.dmg ]]
|
||||
then
|
||||
KIND="bin"
|
||||
else
|
||||
KIND="other"
|
||||
fi
|
||||
# First we try to shorten using just the file name.
|
||||
# If that fails, we use an encoding of the entire path.
|
||||
SHORT1="$(basename "$REPLY")"
|
||||
shorten "$URL" "$SHORT1" "${RELEASE_TAG}_${KIND}" "${RELEASE_TAG}" "${KIND}"
|
||||
if [[ $? != 0 ]]
|
||||
then
|
||||
SHORT2="${REPLY//\//_}"
|
||||
shorten "$URL" "$SHORT2" "${RELEASE_TAG}_${KIND}" "${RELEASE_TAG}" "${KIND}"
|
||||
if [[ $? != 0 ]]
|
||||
then
|
||||
echo "Sorry, could not create a short link."
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
done
|
||||
done
|
||||
Loading…
Reference in New Issue