[Releng] Build publication

Initial scripts for publishing Papyrus Compare builds.

Change-Id: I14ee94a1b13bb0b68e92bfdef13c4e699c48d56b
diff --git a/plugins/compare/releng/.project b/plugins/compare/releng/.project
new file mode 100644
index 0000000..00c52e3
--- /dev/null
+++ b/plugins/compare/releng/.project
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>Papyrus Compare Releng</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+	</buildSpec>
+	<natures>
+	</natures>
+</projectDescription>
diff --git a/plugins/compare/releng/scripts/common.sh b/plugins/compare/releng/scripts/common.sh
new file mode 100644
index 0000000..ec64ed7
--- /dev/null
+++ b/plugins/compare/releng/scripts/common.sh
@@ -0,0 +1,255 @@
+#!/bin/sh
+# ====================================================================
+# Copyright (c) 2014, 2018 Obeo and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+#    Obeo - initial API and implementation
+#    Christian W. Damus - Adapt for Papyrus Compare releng
+# ====================================================================
+
+set -ux
+
+# The path to the p2-admin executable
+export P2_ADMIN_PATH="/shared/modeling/emf/compare/p2-admin"
+
+# The root folder for all EMF Compare udpate sites
+export PAPYRUS_COMPARE_UPDATES_ROOT="/home/data/httpd/download.eclipse.org/modeling/mdt/papyrus/components/compare/updates"
+
+# The base URL for all EMF Compare update sites
+export PAPYRUS_COMPARE_UPDATES_BASE_URL="http://download.eclipse.org/modeling/mdt/papyrus/components/compare/updates"
+
+NIGHTLY="nightly"
+NIGHTLY_PREFIX="N"
+INTEGRATION="integration"
+INTEGRATION_PREFIX="I"
+RELEASE="release"
+RELEASE_PREFIX="R"
+PREFIXES="$NIGHTLY_PREFIX$INTEGRATION_PREFIX$RELEASE_PREFIX"
+VERSION_PATTERN="([0-9]+)\.([0-9]+)\.([0-9]+)-?([$PREFIXES])?([0-9]{8}-[0-9]{6})?"
+
+# To avoid error find: paths must precede expression
+# It takes apart the argument list to find and concatenates the arguments back into another 
+# argument list but inserts -regextype posix-awk in front of any -iregex or -regex arguments it finds.
+# see http://superuser.com/a/666634
+findGnuRegex () {
+    args=
+    for arg in $*
+    do
+        case $arg in
+            -ireges|-regex)
+                args="$args -regextype posix-extended $arg"
+                ;;
+            *)
+                args="$args $arg"
+                ;;
+        esac
+    done
+    set -f
+    command find $args
+    set +f
+}
+
+# define alias depending on the underlying OS 
+# e.g., regex on BSD-like and GNU-like OS are not handled through the same options for
+# find and sed.
+if [[ "$OSTYPE" == "linux"* ]]; then
+	alias sed-regex="sed -r"
+	alias find-regex="findGnuRegex"
+elif [[ "$OSTYPE" == "cygwin" ]]; then
+    alias sed-regex="sed -r"
+    alias find-regex="findGnuRegex"
+elif [[ "$OSTYPE" == "freebsd"* ]]; then
+	alias sed-regex="sed -E"
+	alias find-regex="find -E"
+elif [[ "$OSTYPE" == "darwin"* ]]; then
+	alias sed-regex="sed -E"
+	alias find-regex="find -E"
+else
+	echo "Unknown 'OSTYPE'=$OSTYPE."
+	exit -1
+fi
+
+chmod u+x $P2_ADMIN_PATH
+alias p2-admin="${JAVA_HOME}/bin/java -jar $P2_ADMIN_PATH/plugins/org.eclipse.equinox.launcher_*.jar"
+alias composite-repository="p2-admin -application org.eclipselabs.equinox.p2.composite.repository -compressed"
+
+# Create a p2 index file for composite repositories
+createP2Index() {
+	    cat > "$1/p2.index" <<EOF
+version = 1
+metadata.repository.factory.order = compositeContent.xml,\!
+artifact.repository.factory.order = compositeArtifacts.xml,\!
+EOF
+}
+
+# Remove any previous file from the $1 path and create a composite repository with a single
+# child ($2). The composite will be name $3.
+createRedirect() {
+	local from="$1"
+	local to="$2"
+	local name="$3"
+	
+	mkdir -p "$from"
+	rm -f "$from/compositeArtifacts."*
+	rm -f "$from/compositeContent."*
+	composite-repository -location "$from" -add "$to" -repositoryName "$name"
+	createP2Index $from
+}
+
+strcmp() {
+  local diff
+  for ((i=0; i<=${#1}; ++i)); do
+    if ((diff=$(printf %d \""${1:i:1}") - $(printf %d \""${2:i:1}") ));
+      then echo $diff; return
+    fi
+  done
+  echo 0
+}
+
+# Echo a negative integer, zero, or a positive integer if $1 version is less than, equal to,
+# or greater than the specified $2 version.
+compareOSGIVersions() {
+    local this="$1"
+	local that="$2"
+
+	thisMajor=$(echo "$this" | sed-regex -e 's/'"$VERSION_PATTERN"'/\1/')
+	thisMinor=$(echo "$this" | sed-regex -e 's/'"$VERSION_PATTERN"'/\2/')
+	thisMicro=$(echo "$this" | sed-regex -e 's/'"$VERSION_PATTERN"'/\3/')
+	thisQualifier=$(echo "$this" | sed-regex -e 's/'"$VERSION_PATTERN"'/\4\5/')
+	
+	thatMajor=$(echo "$that" | sed-regex -e 's/'"$VERSION_PATTERN"'/\1/')
+	thatMinor=$(echo "$that" | sed-regex -e 's/'"$VERSION_PATTERN"'/\2/')
+	thatMicro=$(echo "$that" | sed-regex -e 's/'"$VERSION_PATTERN"'/\3/')
+	thatQualifier=$(echo "$that" | sed-regex -e 's/'"$VERSION_PATTERN"'/\4\5/')
+	
+	echo "'"$thisMajor"' => '"$thatMajor"'" 1>&2
+	echo "'"$that"'" 1>&2
+	if [ "$thisMajor" -ne "$thatMajor" ]; then
+		echo $(($thisMajor-$thatMajor))  1>&2
+	elif [ "$thisMinor" -ne "$thatMinor" ]; then
+		echo $(($thisMinor-$thatMinor))	 1>&2
+	elif [ "$thisMicro" -ne "$thatMicro" ]; then
+		echo $(($thisMicro-$thatMicro))  1>&2
+	elif [[ "$thisQualifier" != "$thatQualifier" ]]; then
+		echo strcmp $thisQualifier $thatQualifier 1>&2
+	else
+		echo 0  1>&2
+	fi
+	echo 0
+}
+
+# print all major versions (sorted) in the $1 path on the standard output
+# the output will be a list of integer
+allMajors() {
+	local path="$1"
+	find-regex "$path" -regex '^'"$path"'/?'"$VERSION_PATTERN"'$' -type d \
+		| sed-regex -e 's#^'"$path"'/?([0-9]+)\.([0-9]+)\.([0-9]+)-(['"$PREFIXES"'])([0-9]{8})-([0-9]{6})$#\1#' \
+		| sort -un
+}
+
+# print all minor versions (sorted) for the given $2 major version in the $1 path on the standard output
+# $2 must be an integer
+# the output will be a list of the form X.Y
+allMinors() {
+	local path="$1"
+	local major="$2"
+	find-regex "$path" -regex '^'"$path"'/?'"$major"'\.[0-9]+\.[0-9]+-['"$PREFIXES"'][0-9]{8}-[0-9]{6}$' -type d \
+		| sed-regex -e 's#^'"$path"'/?([0-9]+)\.([0-9]+)\.([0-9]+)-(['"$PREFIXES"'])([0-9]{8})-([0-9]{6})$#\2#' \
+		| sort -un
+}
+
+# print all micro versions (sorted) for the given $2 minor version in the $1 path on the standard output
+# $2 must be of the form x.y where x and y are integer
+# the output will be a list of the form X.Y.Z
+allMicros() {
+	local path="$1"
+	local major="$2"
+	local minor="$3"
+	find-regex "$path" -regex '^'"$path"'/?'"$major"'\.'"$minor"'\.[0-9]+-['"$PREFIXES"'][0-9]{8}-[0-9]{6}$' -type d \
+		| sed-regex -e 's#^'"$path"'/?([0-9]+)\.([0-9]+)\.([0-9]+)-(['"$PREFIXES"'])([0-9]{8})-([0-9]{6})$#\3#' \
+		| sort -un
+}
+
+# print all builds (sorted) for the given $2 micro version in the $1 path on the standard output
+# $2 must be of the form x.y.z where x, y and z are integer
+# the output will be a list of the form X.Y.Z-NYYYYMMDD-HHMMSS
+allBuilds() {
+	local path="$1"
+	local major="$2"
+	local minor="$3"
+	local micro="$4"
+	find-regex "$path" -regex '^'"$path"'/?'"$major"'\.'"$minor"'\.'"$micro"'-['"$PREFIXES"'][0-9]{8}-[0-9]{6}$' -type d \
+		| sed-regex -e 's#'"$path"'/?##' \
+		| sort -u
+}
+
+# visit all the builds in $1 path and call the $2 callback for each.
+# $3 should the version of interest for this call. It is not used by this function but
+# is given to the $2 callback.
+#
+# The callback must accept 10 parameters:
+#  1/ the path (equals to $1)
+#  2/ the version of interrest (equals to $3)
+#  3/ the currently visited major version (an integer)
+#  4/ the currently visited minor version (an integer)
+#  5/ the currently visited micro version (an integer)
+#  6/ the currently visited build (format x.y.z-TYYYYMMDD-HHMM, where x, y and z 
+#     are integer, T is N for nightly, I for integration or R for release and YYYYMMDD-HHMM is a timestamp)
+#  7/ the most recent major version in the given $1 path (an integer)
+#  8/ the most recent minor version in the currently visited major version (an integer)
+#  9/ the most recent micro version in the currently visited minor version (an integer)
+#  10/ the most recent build version in the currently visited micro version (format x.y.z-TYYYYMMDD-HHMM, where x, y and z 
+#     are integer, T is N for nightly, I for integration or R for release and YYYYMMDD-HHMM is a timestamp)
+visitVersions() {
+	local path="$1"
+	local callback="$2"
+	local version="$3"
+
+	allMajors=$(allMajors "$path")
+	latestMajor=$(echo "$allMajors" | tail -1)
+	for major in $allMajors
+	do
+		allMinors=$(allMinors "$path" "$major")
+		latestMinor=$(echo "$allMinors" | tail -1)
+		for minor in $allMinors
+		do
+			allMicros=$(allMicros "$path" "$major" "$minor")
+			latestMicro=$(echo "$allMicros" | tail -1)
+			for micro in $allMicros
+			do
+				allBuilds=$(allBuilds "$path" "$major" "$minor" "$micro")
+				latestBuild=$(echo "$allBuilds" | tail -1)
+
+				for build in $allBuilds
+				do
+					$callback "$path" "$version" "$major" "$minor" "$micro" "$build" "$latestMajor" "$latestMinor" "$latestMicro" "$latestBuild" 
+				done
+			done
+		done
+	done
+}
+
+# Get the name of the minor stream from the $1 full version X.Y.Z.
+# Example: majorStream 2.3.2 => 2.3.x
+minorStream() {
+	local version="$1"
+	echo "$version" | sed-regex -e 's/^([0-9]+\.[0-9]+\.).*$/\1x/'
+}
+
+# Get the name of the major stream from the $1 full version X.Y.Z.
+# Example: majorStream 2.3.2 => 2.x
+majorStream() {
+	local version="$1"
+	echo "$version" | sed-regex -e 's/^([0-9]+\.).*$/\1x/'
+}
+
+# Converts the Hudson build id $1 (e.g. 2013-10-15_07-07-07) into the
+# syntax we want for our update-sites (e.g. 20131015-070707)
+buildTimestamp() {
+	local buildId="$1"
+	echo "$buildId" | sed -e 's/-//g' -e 's/_/-/'
+}
diff --git a/plugins/compare/releng/scripts/publish-nightly.sh b/plugins/compare/releng/scripts/publish-nightly.sh
new file mode 100755
index 0000000..7303cf7
--- /dev/null
+++ b/plugins/compare/releng/scripts/publish-nightly.sh
@@ -0,0 +1,284 @@
+#!/bin/sh
+# ====================================================================
+# Copyright (c) 2014, 2018 Obeo and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+#    Obeo - initial API and implementation
+#    Christian W. Damus - Adapt for Papyrus Compare releng
+# ====================================================================
+
+set -ux
+
+# Get common function and values
+source `dirname $0`/common.sh
+
+######################################################################
+# Constants
+######################################################################
+
+# The type of build being published
+BUILD_TYPE=nightly
+PROG=`basename $0`
+REPOSITORY_PATH="plugins/compare/org.eclipse.papyrus.compare.p2/target/repository"
+HELP=false
+
+######################################################################
+# Arguments processing
+######################################################################
+
+usage() {
+  echo "Usage: "$PROG" [-h] -v version -i build-id -w workspace -r repository"
+  echo "  Options:"
+  echo "    -v, --version     The version to be published. Format is X.Y.Z where X, Y and Z are integer"
+  echo "    -b, --build-type  The build type, one of n[ightly] (default), i[ntegration], or r[elease]"
+  echo "    -i, --build-id    The build ID. Format is YYYY-MM-DD_HH-MM-SS"
+  echo "    -w, --workspace   The folder where the artifacts have been built"
+  echo "    -r, --repository  The repository folder to publish"
+  echo "    -h, --help        Display this help message"
+}
+
+SHORT_OPT_STRING="hw:b:i:v:r:"
+getopt -T > /dev/null
+if [ $? -eq 4 ]; then
+  # GNU enhanced getopt is available
+  ARGS=`getopt --name "$PROG" --long help,workspace:,build-type:,build-id:,version:,repository: --options "$SHORT_OPT_STRING" -- "$@"`
+else
+  # Original getopt is available (no long option names, no whitespace, no sorting)
+  ARGS=`getopt "$SHORT_OPT_STRING" "$@"`
+fi
+if [ $? -ne 0 ]; then
+  usage >&2
+  exit 2
+fi
+eval set -- $ARGS
+
+while [ $# -gt 0 ]; do
+    case "$1" in
+        -h | --help)        HELP=true;;
+        -w | --workspace)   WORKSPACE="$2"; shift;;
+        -b | --build-type)  BUILD_TYPE="$2"; shift;;
+        -i | --build-id)    BUILD_ID="$2"; shift;;
+        -v | --version)     VERSION="$2"; shift;;
+        -r | --repository)  REPOSITORY_PATH="$2"; shift;;
+        --)                 shift; break;; # end of options
+    esac
+    shift
+done
+
+if [ "$HELP" = true ]; then
+  usage
+  exit 0
+fi
+
+if [ -z "$WORKSPACE" ]; then
+  echo "$0: workspace argument is mandatory" >&2
+  usage >&2 
+  exit 1
+fi
+
+if [ ! -d "$WORKSPACE" ]; then
+  echo "$0: workspace does not exist or is not a directory -- $WORKSPACE" >&2
+  usage >&2 
+  exit 1
+fi
+
+if [ -z "$REPOSITORY_PATH" ]; then
+  echo "$0: repository argument is mandatory" >&2
+  usage >&2 
+  exit 1
+fi
+
+if [ ! -d "$REPOSITORY_PATH" ]; then
+  echo "$0: repository does not exist or is not a directory -- $REPOSITORY_PATH" >&2
+  usage >&2 
+  exit 1
+fi
+
+if [ -z "$BUILD_TYPE" ]; then
+  BUILD_TYPE=nightly
+  BUILD_PREFIX=$NIGHTLY_PREFIX
+else
+  BUILD_TYPE=$(echo "$BUILD_TYPE" | tr '[:upper:]' '[:lower:]')
+fi
+
+case "$BUILD_TYPE" in
+  n | nightly)		BUILD_PREFIX=$NIGHTLY_PREFIX;;
+  i | integration)	BUILD_PREFIX=$INTEGRATION_PREFIX;;
+  r | release)		BUILD_PREFIX=$RELEASE_PREFIX;;
+  *) echo "$0: unknown build type '$BUILD_TYPE'" >&2; usage >&2; exit 1;;
+esac
+
+if [ -z "$BUILD_ID" ]; then
+  echo "$0: build-id argument is mandatory" >&2
+  usage >&2 
+  exit 1
+fi 
+
+echo "$BUILD_ID" | grep -E '^[0-9]{4}-[0-9]{2}-[0-9]{2}_[0-9]{2}-[0-9]{2}-[0-9]{2}$' > /dev/null
+if [ $? -ne 0 ]; then
+  echo "$0: bad build-id format -- $BUILD_ID" >&2 
+  usage >&2 
+  exit 1
+fi
+
+if [ -z "$VERSION" ]; then
+  echo "$0: version argument is mandatory" >&2
+  usage >&2 
+  exit 1
+fi 
+
+echo $VERSION | grep -E '^[0-9]+\.[0-9]+\.[0-9]+$' > /dev/null
+if [ $? -ne 0 ]; then
+  echo "$0: bad version format -- $VERSION" >&2 
+  usage >&2 
+  exit 1
+fi
+
+# Exit on error
+set -e
+
+# update the "latest" repositories to the new build. Should be used as a callback in 
+# function visitVersions
+#  1/ the path
+#  2/ the version of interrest
+#  3/ the currently visited major version (an integer)
+#  4/ the currently visited minor version (an integer)
+#  5/ the currently visited micro version (an integer)
+#  6/ the currently visited build (format x.y.z-TYYYYMMDD-HHMM, where x, y and z 
+#     are integer, T is N for nightly, I for integration or R for release and YYYYMMDD-HHMM is a timestamp)
+#  7/ the most recent major version in the given $1 path (an integer)
+#  8/ the most recent minor version in the currently visited major version (an integer)
+#  9/ the most recent micro version in the currently visited minor version (an integer)
+#  10/ the most recent build version in the currently visited micro version (format x.y.z-TYYYYMMDD-HHMM, where x, y and z 
+#     are integer, T is N for nightly, I for integration or R for release and YYYYMMDD-HHMM is a timestamp)
+updateLatestRedirections() {
+	local path=$1
+	local versionToPublish=$2
+	local visitedMajor=$3
+	local visitedMinor=$4
+	local visitedMicro=$5
+	local visitedBuild=$6
+	local latestMajor=$7
+	local latestMinor=$8
+	local latestMicro=$9
+	local latestBuild=${10}
+	
+	local updateSiteURL="$PAPYRUS_COMPARE_UPDATES_BASE_URL/$BUILD_TYPE/$latestBuild"
+
+	local nextMajor="$(($visitedMajor+1)).0.0"
+	local nextMinor="$visitedMajor.$(($visitedMinor+1)).0"
+	local nextMicro="$visitedMajor.$visitedMinor.$(($visitedMicro+1)).0"
+
+	if [ $(compareOSGIVersions $versionToPublish "$visitedMajor.$visitedMinor.$visitedMicro") -ge 0 ]; then
+		if [  $(compareOSGIVersions $versionToPublish $nextMicro) -lt 0 ]; then
+				local stream="$visitedMajor.$visitedMinor.$visitedMicro"
+				echo "    $PAPYRUS_COMPARE_UPDATES_BASE_URL/$BUILD_TYPE/$stream/latest"
+				createRedirect "$path/$stream/latest" "$updateSiteURL" "Papyrus Compare latest $stream $BUILD_TYPE build"
+		fi 
+
+		if [ "$visitedMicro" -eq "$latestMicro" ]; then
+			if [ $(compareOSGIVersions $versionToPublish $nextMinor) -lt 0 ]; then
+				local stream="$visitedMajor.$visitedMinor.x"
+				echo "    $PAPYRUS_COMPARE_UPDATES_BASE_URL/$BUILD_TYPE/$stream/latest"
+				createRedirect "$path/$stream/latest" "$updateSiteURL" "Papyrus Compare latest $stream $BUILD_TYPE build"
+			fi
+
+			if [ "$visitedMinor" -eq "$latestMinor" ]; then
+				if [ $(compareOSGIVersions $versionToPublish $nextMajor) -lt 0 ]; then
+					local stream="$visitedMajor.x"
+					echo "    $PAPYRUS_COMPARE_UPDATES_BASE_URL/$BUILD_TYPE/$stream/latest"
+					createRedirect "$path/$stream/latest" "$updateSiteURL" "Papyrus Compare latest $stream $BUILD_TYPE build"
+				fi
+
+				if [ "$visitedMajor" -eq "$latestMajor" ]; then
+					echo "    $PAPYRUS_COMPARE_UPDATES_BASE_URL/$BUILD_TYPE/latest"
+					createRedirect "$path/latest" "$updateSiteURL" "Papyrus Compare latest $BUILD_TYPE build"
+				fi
+			fi
+		fi
+	fi
+
+	return 0
+}
+
+######################################################################
+# Setup
+######################################################################
+
+# MINOR_STREAMs are of the form 1.0.x: only keep major and minor version number parts
+export MINOR_STREAM=$(minorStream "$VERSION")
+
+# MINOR_STREAMs are of the form 1.x: only keep major version number parts
+export MAJOR_STREAM=$(majorStream "$VERSION")
+
+# Converts the Hudson BUILD_ID (e.g. 2013-10-15_07-07-07) into the
+# syntax we want for our update-sites (e.g. 20131015-070707)
+export BUILD_TIMESTAMP=$(buildTimestamp "$BUILD_ID")
+
+# The full version for this build, e.g. 0.9.0-N20131015-070707
+export FULL_VERSION="${VERSION}-${BUILD_PREFIX}${BUILD_TIMESTAMP}"
+
+# The root folder where all the builds of the same type as this one
+# are published
+export BUILD_PATH="$PAPYRUS_COMPARE_UPDATES_ROOT/$BUILD_TYPE"
+
+# The folder for this particular build
+export UPDATE_SITE_PATH=
+
+# The URL on which this particular build will be made available
+export UPDATE_SITE_URL="$PAPYRUS_COMPARE_UPDATES_BASE_URL/$BUILD_TYPE/$FULL_VERSION"
+
+######################################################################
+# Publish the build
+######################################################################
+
+echo "Publishing build $BUILD_PATH/$FULL_VERSION to $UPDATE_SITE_URL"
+
+# Ensure the target folder exists
+mkdir -p "$BUILD_PATH/$FULL_VERSION"
+# The actual publication of the p2 repo produced by the build
+cp -a "$WORKSPACE/$REPOSITORY_PATH/"* "$BUILD_PATH/$FULL_VERSION"
+# Also publish a dump of the build environment, may be useful to debug
+env | sort > "$BUILD_PATH/$FULL_VERSION/build_env.txt"
+
+echo "Adding $UPDATE_SITE_URL to composites repositories:"
+
+# add a link for the $VERSION (e.g. "1.2.0" => "1.2.0-NYYYYMMDD-HHMM")
+echo "    $PAPYRUS_COMPARE_UPDATES_BASE_URL/$BUILD_TYPE/$VERSION"
+composite-repository \
+	-location "$BUILD_PATH/$VERSION" \
+	-add "$UPDATE_SITE_URL" \
+	-repositoryName "Papyrus Compare $VERSION $BUILD_TYPE builds"
+createP2Index "$BUILD_PATH/$VERSION"
+
+# add a link for the $MINOR_STREAM (e.g. "1.2.x" => "1.2.0-NYYYYMMDD-HHMM")
+echo "    $PAPYRUS_COMPARE_UPDATES_BASE_URL/$BUILD_TYPE/$MINOR_STREAM"
+composite-repository \
+	-location "$BUILD_PATH/$MINOR_STREAM" \
+	-add "$UPDATE_SITE_URL" \
+	-repositoryName "Papyrus Compare $MINOR_STREAM $BUILD_TYPE builds"
+createP2Index "$BUILD_PATH/$MINOR_STREAM"
+
+# add a link for the $MAJOR_STREAM (e.g. "1.x" => "1.2.0-NYYYYMMDD-HHMM")
+echo "    $PAPYRUS_COMPARE_UPDATES_BASE_URL/$BUILD_TYPE/$MAJOR_STREAM"
+composite-repository \
+	-location "$BUILD_PATH/$MAJOR_STREAM" \
+	-add "$UPDATE_SITE_URL" \
+	-repositoryName "Papyrus Compare $MAJOR_STREAM $BUILD_TYPE builds"
+createP2Index "$BUILD_PATH/$MAJOR_STREAM"
+
+# add a link for all nightly list
+echo "    $PAPYRUS_COMPARE_UPDATES_BASE_URL/$BUILD_TYPE"
+composite-repository \
+	-location "$BUILD_PATH" \
+	-add "$UPDATE_SITE_URL" \
+	-repositoryName "Papyrus Compare $BUILD_TYPE builds"
+createP2Index "$BUILD_PATH"
+
+# Setup or update the redirects (implemented as composite repos)
+echo "Redirecting 'latest' repositories to $UPDATE_SITE_URL:"
+visitVersions "$BUILD_PATH" "updateLatestRedirections" $VERSION