Skip to content

JSONP release job

Dmitry Kornilov edited this page Sep 18, 2018 · 5 revisions

Goal: Create a Jenkins job to publish project artifacts to OSSRH.
Author: Tomas Kraus

Jenkins Environment Setup

We don't have rights to setup Jenkins environment on ci.eclipse.org so most of the steps are done via requests in Eclipse Bugzilla.

Common requests for each EE4J project:

  • Jenkins CI for given project
  • List of Jenkins plugins you need
  • GitHub repository access with write permissions (ssh, keys, ssh-agent)
  • OSSRH space for project and access permissions
  • GPG plugin setup

Eclipse Request

New bug in Bugzilla:

  • Classification: Eclipse Foundation - Community bugs
  • Product: Community - Eclipse.org community services
  • Component: CI-Jenkins
  • Description: Your request (what should be installed or configured)

You can use this shortcut: https://bugs.eclipse.org/bugs/enter_bug.cgi?product=Community

You can put all the requests in a single bug to reduce bureaucracy as much as possible.

Sample: https://bugs.eclipse.org/bugs/show_bug.cgi?id=538637

Release Job

Job Execution Environment

Jenkins job needs specific settings to get access to Java and Maven:

TOOLS_PREFIX='/shared/common'
MVN_HOME="${TOOLS_PREFIX}/apache-maven-latest"
JAVA_HOME="${TOOLS_PREFIX}/jdk-9_x64-latest"
PATH="${MVN_HOME}/bin:${JAVA_HOME}:/bin:${PATH}"
# Maven plugins
HELP_PLUGIN='org.apache.maven.plugins:maven-help-plugin:2.1.1'

Input Parameters

Following parameters are common to all release jobs:

  • RELEASE_VERSION: Version string matching https://semver.org/ rules, e.g. 1.2, 1.1.3, ...
  • NEXT_VERSION: Version string for next development cycle. Usually release version with latest version component increased by one and with -SNAPSHOT suffix appended.
  • BRANCH: Name of GitHub project branch to release. The most common value is master, but any other existing branch name may be used.

Following parameters are related to JSR specification version and API projects:

  • SPEC_VERSION: JSR specification version implemented by API project release. Version string matching https://semver.org/ rules, e.g. 1.2, 1.1.3, ...

Additional parameters allows additional job customization:

  • DRY_RUN: Do not publish artifacts. This checkbox skips maven deploy target and will not push tag and branch to GitHub.
  • OVERWRITE: true (checked): If release with given version string already exists, it's overwritten with new artifacts. Both OSSRH staging repository and GitHub branch and tag are updated. false (unchecked): If release with given version string already exists, job will be terminated with an error.

Input Parameters Processing

In following example Release version and Next version strings are being automatically generated when no values were provided in the input parameters form:

# Compute release versions
SNAPSHOT_VERSION=`mvn -B ${HELP_PLUGIN}:evaluate -Dexpression=project.version 2> /dev/null | grep -E '^[0-9]+(\.[0-9]+)+-SNAPSHOT$'`
 
if [ -z "${RELEASE_VERSION}" ]; then
  if [ -z ${SNAPSHOT_VERSION} ]; then
    echo '-[ Missing required snapshot version number! ]----------------------------------'
  fi
  RELEASE_VERSION=`echo ${SNAPSHOT_VERSION} | sed -e 's/-SNAPSHOT//'`
fi
 
if [ -z "${NEXT_VERSION}" ]; then
  NEXT_VERSION=`echo ${RELEASE_VERSION} | sed -e 's/\([0-9][0-9]*\.[0-9][0-9]*\).*/\1/'`
  set -f
  NEXT_COMPONENTS=(${RELEASE_VERSION//\./ })
  LAST_INDEX=$((${#NEXT_COMPONENTS[@]} - 1))
  NEXT_COMPONENTS[${LAST_INDEX}]=$((${NEXT_COMPONENTS[${LAST_INDEX}]} + 1))
  NEXT_VERSION=`echo ${NEXT_COMPONENTS[@]} | tr ' ' '.'`'-SNAPSHOT'
fi
 
RELEASE_TAG="${RELEASE_VERSION}-RELEASE"
 
echo "Current version: ${SNAPSHOT_VERSION}"
echo "Release version: ${RELEASE_VERSION}"
echo "Next version:    ${NEXT_VERSION}"
echo "Release tag:     ${RELEASE_TAG}"
 
if [ -z "${SNAPSHOT_VERSION}" -o -z "${RELEASE_VERSION}" -o -z "${NEXT_VERSION}" ]; then
  echo '-[ Missing required version numbers! ]------------------------------------------'
  exit 1
fi

Branches and Tags Preparation

If remote repository tag or branch with the same version number exists it means that this version was already uploaded to OSSRH staging repository. Code behavior depends on value of Overwrite input parameter.

echo '-[ Prepare branch ]-------------------------------------------------------------'
GIT_ORIGIN=`git remote`
if [[ -n `git branch -r | grep "${GIT_ORIGIN}/${RELEASE_VERSION}"` ]]; then
  if [ "${OVERWRITE}" = 'true' ]; then
    echo "${GIT_ORIGIN}/${RELEASE_VERSION} branch already exists, deleting"
    git push --delete origin "${RELEASE_VERSION}" && true
  else
    echo "Error: ${GIT_ORIGIN}/${RELEASE_VERSION} branch already exists"
    exit 1
  fi
fi
# Always delete local branch if exists
git branch --delete "${RELEASE_VERSION}" && true
git checkout -b ${RELEASE_VERSION}
 
echo '-[ Release tag cleanup ]--------------------------------------------------------'
if [[ -n `git tag | grep "${RELEASE_TAG}"` ]]; then
  if [ "${OVERWRITE}" = 'true' ]; then
    echo "${RELEASE_TAG} tag already exists, deleting"
    git push --delete origin "${RELEASE_TAG}" && true
  else
    echo "Error: ${RELEASE_TAG} tag already exists"
    exit 1
  fi
fi
# Always delete local tag if exists
git tag --delete "${RELEASE_TAG}" && true

Invoking Maven Release Plugin

The most simple way is to let release plugin do rest of the job:

if [ ${DRY_RUN} = 'true' ]; then
  echo '-[ Dry run turned on ]----------------------------------------------------------'
  MVN_ARGS='-DdryRun=true'
else
  MVN_ARGS=''
fi
 
echo '-[ Run maven release plugin ]---------------------------------------------------'
mvn -U -C -s /opt/public/hipp/homes/genie.jsonp/.m2/settings-deploy-ossrh.xml \
    ${MVN_ARGS} \
    -Prelease,!jdk9-all \
    -DskipTests \
    -Drelease.arguments="-s /opt/public/hipp/homes/genie.jsonp/.m2/settings-deploy-ossrh.xml -Prelease,!jdk9-all -DskipTests -Dspec_version=${SPEC_VERSION} -Dimpl_version=${RELEASE_VERSION}" \
    -DreleaseProfiles='release' \
    -Dtag="${RELEASE_TAG}" \
    -DreleaseVersion="${RELEASE_VERSION}" \
    -DdevelopmentVersion="${NEXT_VERSION}" \
    -Dspec_version=${SPEC_VERSION} \
    -Dimpl_version=${RELEASE_VERSION} \
    release:prepare release:perform

Full Job Script

Jenkins job screenshot is available here. Job script is copied below for convenience.

#!/bin/bash -e

# Execution environment
TOOLS_PREFIX='/shared/common'
MVN_HOME="${TOOLS_PREFIX}/apache-maven-latest"
JAVA_HOME="${TOOLS_PREFIX}/jdk-9_x64-latest"
PATH="${MVN_HOME}/bin:${JAVA_HOME}:/bin:${PATH}"
# Maven plugins
HELP_PLUGIN='org.apache.maven.plugins:maven-help-plugin:2.1.1'

# Check whether top level pom.xml contains SNAPSHOT version
if ! grep '<version>' pom.xml | grep 'SNAPSHOT' ; then
  echo '-[ Missing SNAPSHOT version in POM! ]-------------------------------------------'
  exit 1
fi

# Compute release versions
SNAPSHOT_VERSION=`mvn -B ${HELP_PLUGIN}:evaluate -Dexpression=project.version 2> /dev/null | grep -E '^[0-9]+(\.[0-9]+)+-SNAPSHOT$'`

if [ -z "${RELEASE_VERSION}" ]; then
  if [ -z ${SNAPSHOT_VERSION} ]; then
    echo '-[ Missing required snapshot version number! ]----------------------------------'
  fi
  RELEASE_VERSION=`echo ${SNAPSHOT_VERSION} | sed -e 's/-SNAPSHOT//'`
fi

if [ -z "${NEXT_VERSION}" ]; then
  NEXT_VERSION=`echo ${RELEASE_VERSION} | sed -e 's/\([0-9][0-9]*\.[0-9][0-9]*\).*/\1/'`
  set -f
  NEXT_COMPONENTS=(${RELEASE_VERSION//\./ })
  LAST_INDEX=$((${#NEXT_COMPONENTS[@]} - 1))
  NEXT_COMPONENTS[${LAST_INDEX}]=$((${NEXT_COMPONENTS[${LAST_INDEX}]} + 1))
  NEXT_VERSION=`echo ${NEXT_COMPONENTS[@]} | tr ' ' '.'`'-SNAPSHOT'
fi

RELEASE_TAG="${RELEASE_VERSION}-RELEASE"

echo "Current version: ${SNAPSHOT_VERSION}"
echo "Release version: ${RELEASE_VERSION}"
echo "Next version:    ${NEXT_VERSION}"
echo "Release tag:     ${RELEASE_TAG}"

if [ -z "${SNAPSHOT_VERSION}" -o -z "${RELEASE_VERSION}" -o -z "${NEXT_VERSION}" ]; then
  echo '-[ Missing required version numbers! ]------------------------------------------'
  exit 1
fi

if [ ${DRY_RUN} = 'true' ]; then
  echo '-[ Dry run turned on ]----------------------------------------------------------'
  MVN_ARGS='-DdryRun=true'
else
  MVN_ARGS=''
fi

echo '-[ Prepare branch ]-------------------------------------------------------------'
GIT_ORIGIN=`git remote`
if [[ -n `git branch -r | grep "${GIT_ORIGIN}/${RELEASE_VERSION}"` ]]; then
  if [ "${OVERWRITE}" = 'true' ]; then
    echo "${GIT_ORIGIN}/${RELEASE_VERSION} branch already exists, deleting"
    git push --delete origin "${RELEASE_VERSION}" && true
  else
    echo "Error: ${GIT_ORIGIN}/${RELEASE_VERSION} branch already exists"
    exit 1
  fi
fi
# Always delete local branch if exists
git branch --delete "${RELEASE_VERSION}" && true
git checkout -b ${RELEASE_VERSION}

echo '-[ Release tag cleanup ]--------------------------------------------------------'
if [[ -n `git tag | grep "${RELEASE_TAG}"` ]]; then
  if [ "${OVERWRITE}" = 'true' ]; then
    echo "${RELEASE_TAG} tag already exists, deleting"
    git push --delete origin "${RELEASE_TAG}" && true
  else
    echo "Error: ${RELEASE_TAG} tag already exists"
    exit 1
  fi
fi
# Always delete local tag if exists
git tag --delete "${RELEASE_TAG}" && true

java -version
mvn -version
echo $JAVA_HOME

echo '-[ Run maven release plugin ]---------------------------------------------------'
#    -Dspec_version=${SPEC_VERSION} \
#    -Dimpl_version=${RELEASE_VERSION} \
#    -Dnew_spec_version=${SPEC_VERSION} \
#    -Dnew_impl_version=${RELEASE_VERSION} \
#    -DpushChanges=false \
# Prepare release
mvn -U -C -s /opt/public/hipp/homes/genie.jsonp/.m2/settings-deploy-ossrh.xml \
    ${MVN_ARGS} \
    -Prelease,!jdk9-all \
    -DskipTests \
    -Drelease.arguments="-s /opt/public/hipp/homes/genie.jsonp/.m2/settings-deploy-ossrh.xml -Prelease,!jdk9-all -DskipTests -Dspec_version=${SPEC_VERSION} -Dimpl_version=${RELEASE_VERSION}" \
    -DreleaseProfiles='release' \
    -Dtag="${RELEASE_TAG}" \
    -DreleaseVersion="${RELEASE_VERSION}" \
    -DdevelopmentVersion="${NEXT_VERSION}" \
    -Dspec_version=${SPEC_VERSION} \
    -Dimpl_version=${RELEASE_VERSION} \
    release:prepare release:perform

Links