[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