Notice: This Wiki is now read only and edits are no longer possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.
Difference between revisions of "JakartaEE New Infra Release Job"
(8 intermediate revisions by the same user not shown) | |||
Line 49: | Line 49: | ||
TOOLS_PREFIX='/opt/tools' | TOOLS_PREFIX='/opt/tools' | ||
− | JAVA_PREFIX="${TOOLS_PREFIX}/java/ | + | JAVA_PREFIX="${TOOLS_PREFIX}/java/openjdk" |
MVN_HOME="${TOOLS_PREFIX}/apache-maven/latest" | MVN_HOME="${TOOLS_PREFIX}/apache-maven/latest" | ||
− | JAVA_HOME="${JAVA_PREFIX}/jdk- | + | JAVA_HOME="${JAVA_PREFIX}/jdk-11/latest" |
PATH="${MVN_HOME}/bin:${JAVA_HOME}/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" | PATH="${MVN_HOME}/bin:${JAVA_HOME}/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" | ||
</pre> | </pre> | ||
Line 63: | Line 63: | ||
<pre> | <pre> | ||
# Maven plugins | # Maven plugins | ||
− | VERSIONS_PLUGIN='org.codehaus.mojo:versions-maven-plugin:2. | + | VERSIONS_PLUGIN='org.codehaus.mojo:versions-maven-plugin:2.7' |
− | HELP_PLUGIN='org.apache.maven.plugins:maven-help-plugin: | + | HELP_PLUGIN='org.apache.maven.plugins:maven-help-plugin:3.1.0' |
− | |||
# Check whether top level pom.xml contains SNAPSHOT version | # Check whether top level pom.xml contains SNAPSHOT version | ||
if ! grep '<version>' pom.xml | grep 'SNAPSHOT' ; then | if ! grep '<version>' pom.xml | grep 'SNAPSHOT' ; then | ||
Line 74: | Line 73: | ||
# Compute release versions | # Compute release versions | ||
− | SNAPSHOT_VERSION=`mvn -B ${HELP_PLUGIN}:evaluate -Dexpression=project.version 2> /dev/null | grep -E '^[0-9]+(\.[0-9]+)+-SNAPSHOT$'` | + | SNAPSHOT_VERSION=`mvn -B ${HELP_PLUGIN}:evaluate -Pstaging -Dexpression=project.version 2> /dev/null | grep -E '^[0-9]+(\.[0-9]+)+-SNAPSHOT$'` |
if [ -z "${RELEASE_VERSION}" ]; then | if [ -z "${RELEASE_VERSION}" ]; then | ||
Line 112: | Line 111: | ||
Old local release branch and tag are always deleted if exist and local release branch is initialized to store all code changes related to this release. | Old local release branch and tag are always deleted if exist and local release branch is initialized to store all code changes related to this release. | ||
GitHub bot name and e-mail are set in git configuration. | GitHub bot name and e-mail are set in git configuration. | ||
+ | |||
<pre> | <pre> | ||
if [ ${DRY_RUN} = 'true' ]; then | if [ ${DRY_RUN} = 'true' ]; then | ||
Line 118: | Line 118: | ||
echo '-[ Skipping GitHub branch and tag checks ]--------------------------------------' | echo '-[ Skipping GitHub branch and tag checks ]--------------------------------------' | ||
else | else | ||
− | MVN_DEPLOY_ARGS=' | + | MVN_DEPLOY_ARGS='nexus-staging:deploy' |
GIT_ORIGIN=`git remote` | GIT_ORIGIN=`git remote` | ||
echo '-[ Prepare branch ]-------------------------------------------------------------' | echo '-[ Prepare branch ]-------------------------------------------------------------' | ||
Line 124: | Line 124: | ||
if [ "${OVERWRITE}" = 'true' ]; then | if [ "${OVERWRITE}" = 'true' ]; then | ||
echo "${GIT_ORIGIN}/${RELEASE_VERSION} branch already exists, deleting" | echo "${GIT_ORIGIN}/${RELEASE_VERSION} branch already exists, deleting" | ||
− | git push --delete | + | git push --delete ${GIT_ORIGIN} "${RELEASE_VERSION}" && true |
else | else | ||
echo "Error: ${GIT_ORIGIN}/${RELEASE_VERSION} branch already exists" | echo "Error: ${GIT_ORIGIN}/${RELEASE_VERSION} branch already exists" | ||
Line 134: | Line 134: | ||
if [ "${OVERWRITE}" = 'true' ]; then | if [ "${OVERWRITE}" = 'true' ]; then | ||
echo "${RELEASE_TAG} tag already exists, deleting" | echo "${RELEASE_TAG} tag already exists, deleting" | ||
− | git push --delete | + | git push --delete ${GIT_ORIGIN} "${RELEASE_TAG}" && true |
else | else | ||
echo "Error: ${RELEASE_TAG} tag already exists" | echo "Error: ${RELEASE_TAG} tag already exists" | ||
Line 156: | Line 156: | ||
GPG setup is missing in Docker image and GPG keys are passed in KEYRING environment variables. Content of this variable must be processed and stored into GPG key store. | GPG setup is missing in Docker image and GPG keys are passed in KEYRING environment variables. Content of this variable must be processed and stored into GPG key store. | ||
+ | |||
<pre> | <pre> | ||
# Workaround: GPG initialization | # Workaround: GPG initialization | ||
Line 167: | Line 168: | ||
=== Set Release Version === | === Set Release Version === | ||
− | Project Group ID and Artifact ID values are retrieved from maven project (<code>pom.xml</code>). Those values are used in git commit messages. | + | Project Group ID and Artifact ID values are retrieved from maven project (<code>pom.xml</code>). Those values are used in git commit messages and nexus deployments description. |
Release version is set in maven project (<code>pom.xml</code>). | Release version is set in maven project (<code>pom.xml</code>). | ||
Updated project is stored in git release branch with corresponding message. | Updated project is stored in git release branch with corresponding message. | ||
+ | <code>${VERSIONS_PLUGIN}:update-parent</code> is not required to update project versions in most cases so you may remove it from both version updating maven calls. But there are exceptions like ''jaxb-ri'' or ''metro-jax-ws'' with <code>boms</code> where parent must be updated too. | ||
+ | |||
<pre> | <pre> | ||
# Project identifiers | # Project identifiers | ||
− | ARTIFACT_ID=$(mvn -B ${HELP_PLUGIN}:evaluate -Dexpression=project.artifactId | grep -Ev '(^\[)') | + | ARTIFACT_ID=$(mvn -B ${HELP_PLUGIN}:evaluate -Dexpression=project.artifactId -Pstaging | grep -Ev '(^\[)') |
− | GROUP_ID=$(mvn -B ${HELP_PLUGIN}:evaluate -Dexpression=project.groupId | grep -Ev '(^\[)') | + | GROUP_ID=$(mvn -B ${HELP_PLUGIN}:evaluate -Dexpression=project.groupId -Pstaging | grep -Ev '(^\[)') |
+ | STAGING_DESC="${GROUP_ID}:${ARTIFACT_ID}:${RELEASE_VERSION}" | ||
+ | STAGING_KEY=$(echo ${STAGING_DESC} | sed -e 's/\./\\\./g') | ||
+ | </pre> | ||
+ | <pre> | ||
echo '-[ Set release version ]--------------------------------------------------------' | echo '-[ Set release version ]--------------------------------------------------------' | ||
# Set release version | # Set release version | ||
− | mvn -U -C \ | + | mvn -U -C -B -Pstaging \ |
− | -DnewVersion="${RELEASE_VERSION}" \ | + | -DnewVersion="${RELEASE_VERSION}" -DparentVersion="${RELEASE_VERSION}" \ |
− | -DgenerateBackupPoms=false \ | + | -DprocessAllModules=true -DgenerateBackupPoms=false \ |
− | clean ${VERSIONS_PLUGIN}:set | + | clean ${VERSIONS_PLUGIN}:set ${VERSIONS_PLUGIN}:update-parent |
echo '-[ Commit modified pom.xml files ]----------------------------------------------' | echo '-[ Commit modified pom.xml files ]----------------------------------------------' | ||
Line 190: | Line 197: | ||
=== Build and Deploy Artifacts === | === Build and Deploy Artifacts === | ||
− | All | + | Old Nexus deployments with the same description <code>groupId:artifactId:version</code> are dropped. |
+ | All artifacts are built and deployed to the staging repository. | ||
Code with release versions is tagged with release tag. | Code with release versions is tagged with release tag. | ||
This maven task requires specific <code>settings.xml</code> file with GPG setup. | This maven task requires specific <code>settings.xml</code> file with GPG setup. | ||
− | Profile <code>oss-release</code> is defined in parent POM. It contains setup for packaging sources and javadoc and specific setup for GPG signing plugin (<code>--pinentry-mode loopback</code>). Minimal version of parent POM is <code>1.0. | + | Profile <code>oss-release</code> is defined in parent POM. It contains setup for packaging sources and javadoc and specific setup for GPG signing plugin (<code>--pinentry-mode loopback</code>). Minimal version of parent POM is <code>1.0.5</code>. |
Project's pom.xml must define versions for the following plugins: | Project's pom.xml must define versions for the following plugins: | ||
* maven-enforcer-plugin | * maven-enforcer-plugin | ||
Line 201: | Line 209: | ||
<pre> | <pre> | ||
+ | echo '-[ Drop old staging repository deployments ]------------------------------------' | ||
+ | for staging_key in $(mvn -B nexus-staging:rc-list -Pstaging | egrep "^\[INFO\] [A-Z,a-z,-]+-[0-9]+\s+[A-Z]+\s+${STAGING_KEY}" | awk '{print $2}'); do | ||
+ | echo "Repository ID: ${staging_key}" | ||
+ | mvn -U -C -B -Pstaging \ | ||
+ | -DstagingRepositoryId="${staging_key}" \ | ||
+ | nexus-staging::rc-drop | ||
+ | done | ||
echo '-[ Deploy artifacts to staging repository ]-------------------------------------' | echo '-[ Deploy artifacts to staging repository ]-------------------------------------' | ||
− | mvn -U -C - | + | mvn -U -C -B -Poss-release,staging \ |
− | -DskipTests -Ddoclint=none - | + | -DskipTests -Ddoclint=none \ |
+ | -DstagingDescription="${STAGING_DESC}" \ | ||
clean package source:jar javadoc:jar gpg:sign install:install ${MVN_DEPLOY_ARGS} | clean package source:jar javadoc:jar gpg:sign install:install ${MVN_DEPLOY_ARGS} | ||
− | |||
echo '-[ Tag release ]----------------------------------------------------------------' | echo '-[ Tag release ]----------------------------------------------------------------' | ||
git tag "${RELEASE_TAG}" -m "Release ${GROUP_ID}:${ARTIFACT_ID}:${RELEASE_VERSION}" | git tag "${RELEASE_TAG}" -m "Release ${GROUP_ID}:${ARTIFACT_ID}:${RELEASE_VERSION}" | ||
Line 216: | Line 231: | ||
<pre> | <pre> | ||
echo '-[ Set next snapshot version ]--------------------------------------------------' | echo '-[ Set next snapshot version ]--------------------------------------------------' | ||
− | mvn -U -C \ | + | mvn -U -C -B -Pstaging \ |
− | -DnewVersion="${NEXT_VERSION}" \ | + | -DnewVersion="${NEXT_VERSION}" -DparentVersion="${NEXT_VERSION}" \ |
− | -DgenerateBackupPoms=false \ | + | -DprocessAllModules=true -DgenerateBackupPoms=false \ |
− | clean ${VERSIONS_PLUGIN}:set | + | clean ${VERSIONS_PLUGIN}:set ${VERSIONS_PLUGIN}:update-parent |
echo '-[ Commit modified pom.xml files ]----------------------------------------------' | echo '-[ Commit modified pom.xml files ]----------------------------------------------' | ||
Line 225: | Line 240: | ||
git add ${POM_FILES} && \ | git add ${POM_FILES} && \ | ||
git commit -m "Prepare next development cycle for ${NEXT_VERSION}" | git commit -m "Prepare next development cycle for ${NEXT_VERSION}" | ||
+ | </pre> | ||
+ | NOTE: Once you're committed to the release, this release branch should be | ||
+ | '''merged''' into master and '''deleted'''. | ||
+ | This will move master to the next snapshot version and prepare it | ||
+ | for future development. For example: | ||
+ | <pre> | ||
+ | $ git pull -r | ||
+ | $ git merge origin/1.2.3-RELEASE | ||
+ | $ git push origin master | ||
+ | $ git branch -D 1.2.3-RELEASE # deletes local branch, in case it exists | ||
+ | $ git push origin :1.2.3-RELEASE # deletes remote branch | ||
</pre> | </pre> | ||
Line 235: | Line 261: | ||
else | else | ||
echo '-[ Push branch and tag to GitHub ]----------------------------------------------' | echo '-[ Push branch and tag to GitHub ]----------------------------------------------' | ||
− | git push | + | git push ${GIT_ORIGIN} "${RELEASE_VERSION}" |
− | git push | + | git push ${GIT_ORIGIN} "${RELEASE_TAG}" |
fi | fi | ||
</pre> | </pre> | ||
Line 247: | Line 273: | ||
TOOLS_PREFIX='/opt/tools' | TOOLS_PREFIX='/opt/tools' | ||
− | JAVA_PREFIX="${TOOLS_PREFIX}/java/ | + | JAVA_PREFIX="${TOOLS_PREFIX}/java/openjdk" |
MVN_HOME="${TOOLS_PREFIX}/apache-maven/latest" | MVN_HOME="${TOOLS_PREFIX}/apache-maven/latest" | ||
− | JAVA_HOME="${JAVA_PREFIX}/jdk- | + | JAVA_HOME="${JAVA_PREFIX}/jdk-11/latest" |
PATH="${MVN_HOME}/bin:${JAVA_HOME}/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" | PATH="${MVN_HOME}/bin:${JAVA_HOME}/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" | ||
# Maven plugins | # Maven plugins | ||
− | VERSIONS_PLUGIN='org.codehaus.mojo:versions-maven-plugin:2. | + | VERSIONS_PLUGIN='org.codehaus.mojo:versions-maven-plugin:2.7' |
− | HELP_PLUGIN='org.apache.maven.plugins:maven-help-plugin: | + | HELP_PLUGIN='org.apache.maven.plugins:maven-help-plugin:3.1.0' |
# Directory with project top level pom.xml | # Directory with project top level pom.xml | ||
− | BUILD_DIR="${WORKSPACE}/ | + | BUILD_DIR="${WORKSPACE}/jaxws-ri" |
cd ${BUILD_DIR} | cd ${BUILD_DIR} | ||
Line 267: | Line 293: | ||
# Compute release versions | # Compute release versions | ||
− | SNAPSHOT_VERSION=`mvn -B ${HELP_PLUGIN}:evaluate -Dexpression=project.version 2> /dev/null | grep -E '^[0-9]+(\.[0-9]+)+-SNAPSHOT$'` | + | SNAPSHOT_VERSION=`mvn -B ${HELP_PLUGIN}:evaluate -Pstaging -Dexpression=project.version 2> /dev/null | grep -E '^[0-9]+(\.[0-9]+)+-SNAPSHOT$'` |
if [ -z "${RELEASE_VERSION}" ]; then | if [ -z "${RELEASE_VERSION}" ]; then | ||
Line 303: | Line 329: | ||
echo '-[ Skipping GitHub branch and tag checks ]--------------------------------------' | echo '-[ Skipping GitHub branch and tag checks ]--------------------------------------' | ||
else | else | ||
− | MVN_DEPLOY_ARGS=' | + | MVN_DEPLOY_ARGS='nexus-staging:deploy' |
GIT_ORIGIN=`git remote` | GIT_ORIGIN=`git remote` | ||
echo '-[ Prepare branch ]-------------------------------------------------------------' | echo '-[ Prepare branch ]-------------------------------------------------------------' | ||
Line 309: | Line 335: | ||
if [ "${OVERWRITE}" = 'true' ]; then | if [ "${OVERWRITE}" = 'true' ]; then | ||
echo "${GIT_ORIGIN}/${RELEASE_VERSION} branch already exists, deleting" | echo "${GIT_ORIGIN}/${RELEASE_VERSION} branch already exists, deleting" | ||
− | git push --delete | + | git push --delete ${GIT_ORIGIN} "${RELEASE_VERSION}" && true |
else | else | ||
echo "Error: ${GIT_ORIGIN}/${RELEASE_VERSION} branch already exists" | echo "Error: ${GIT_ORIGIN}/${RELEASE_VERSION} branch already exists" | ||
Line 319: | Line 345: | ||
if [ "${OVERWRITE}" = 'true' ]; then | if [ "${OVERWRITE}" = 'true' ]; then | ||
echo "${RELEASE_TAG} tag already exists, deleting" | echo "${RELEASE_TAG} tag already exists, deleting" | ||
− | git push --delete | + | git push --delete ${GIT_ORIGIN} "${RELEASE_TAG}" && true |
else | else | ||
echo "Error: ${RELEASE_TAG} tag already exists" | echo "Error: ${RELEASE_TAG} tag already exists" | ||
Line 346: | Line 372: | ||
cd ${BUILD_DIR} | cd ${BUILD_DIR} | ||
# Project identifiers | # Project identifiers | ||
− | ARTIFACT_ID=$(mvn -B ${HELP_PLUGIN}:evaluate -Dexpression=project.artifactId | grep -Ev '(^\[)') | + | ARTIFACT_ID=$(mvn -B ${HELP_PLUGIN}:evaluate -Dexpression=project.artifactId -Pstaging | grep -Ev '(^\[)') |
− | GROUP_ID=$(mvn -B ${HELP_PLUGIN}:evaluate -Dexpression=project.groupId | grep -Ev '(^\[)') | + | GROUP_ID=$(mvn -B ${HELP_PLUGIN}:evaluate -Dexpression=project.groupId -Pstaging | grep -Ev '(^\[)') |
+ | STAGING_DESC="${GROUP_ID}:${ARTIFACT_ID}:${RELEASE_VERSION}" | ||
+ | STAGING_KEY=$(echo ${STAGING_DESC} | sed -e 's/\./\\\./g') | ||
echo '-[ Set release version ]--------------------------------------------------------' | echo '-[ Set release version ]--------------------------------------------------------' | ||
# Set release version | # Set release version | ||
− | mvn -U -C \ | + | mvn -U -C -B -Pstaging \ |
− | -DnewVersion="${RELEASE_VERSION}" \ | + | -DnewVersion="${RELEASE_VERSION}" -DparentVersion="${RELEASE_VERSION}" \ |
− | -DgenerateBackupPoms=false \ | + | -DprocessAllModules=true -DgenerateBackupPoms=false \ |
− | clean ${VERSIONS_PLUGIN}:set | + | clean ${VERSIONS_PLUGIN}:set ${VERSIONS_PLUGIN}:update-parent |
cd ${WORKSPACE} | cd ${WORKSPACE} | ||
Line 363: | Line 391: | ||
cd ${BUILD_DIR} | cd ${BUILD_DIR} | ||
+ | echo '-[ Drop old staging repository deployments ]------------------------------------' | ||
+ | for staging_key in $(mvn -B nexus-staging:rc-list -Pstaging | egrep "^\[INFO\] [A-Z,a-z,-]+-[0-9]+\s+[A-Z]+\s+${STAGING_KEY}" | awk '{print $2}'); do | ||
+ | echo "Repository ID: ${staging_key}" | ||
+ | mvn -U -C -B -Pstaging \ | ||
+ | -DstagingRepositoryId="${staging_key}" \ | ||
+ | nexus-staging::rc-drop | ||
+ | done | ||
echo '-[ Deploy artifacts to staging repository ]-------------------------------------' | echo '-[ Deploy artifacts to staging repository ]-------------------------------------' | ||
− | mvn -U -C - | + | mvn -U -C -B -Poss-release,staging \ |
− | -DskipTests -Ddoclint=none - | + | -DskipTests -Ddoclint=none \ |
+ | -DstagingDescription="${STAGING_DESC}" \ | ||
clean package source:jar javadoc:jar gpg:sign install:install ${MVN_DEPLOY_ARGS} | clean package source:jar javadoc:jar gpg:sign install:install ${MVN_DEPLOY_ARGS} | ||
Line 374: | Line 410: | ||
cd ${BUILD_DIR} | cd ${BUILD_DIR} | ||
echo '-[ Set next snapshot version ]--------------------------------------------------' | echo '-[ Set next snapshot version ]--------------------------------------------------' | ||
− | mvn -U -C \ | + | mvn -U -C -B -Pstaging \ |
− | -DnewVersion="${NEXT_VERSION}" \ | + | -DnewVersion="${NEXT_VERSION}" -DparentVersion="${NEXT_VERSION}" \ |
− | -DgenerateBackupPoms=false \ | + | -DprocessAllModules=true -DgenerateBackupPoms=false \ |
− | clean ${VERSIONS_PLUGIN}:set | + | clean ${VERSIONS_PLUGIN}:set ${VERSIONS_PLUGIN}:update-parent |
cd ${WORKSPACE} | cd ${WORKSPACE} | ||
Line 389: | Line 425: | ||
else | else | ||
echo '-[ Push branch and tag to GitHub ]----------------------------------------------' | echo '-[ Push branch and tag to GitHub ]----------------------------------------------' | ||
− | git push | + | git push ${GIT_ORIGIN} "${RELEASE_VERSION}" |
− | git push | + | git push ${GIT_ORIGIN} "${RELEASE_TAG}" |
fi | fi | ||
</pre> | </pre> | ||
− | == | + | == [https://wiki.eclipse.org/JakartaEE_New_Infra_Release_Job_Screenshots Screenshots] == |
− | + | ||
− | [ | + |
Latest revision as of 15:44, 11 March 2020
Following Jenkins job allows to release project component from any branch of specific GitHub repository. Features:
- automatic version numbers generation
- existing version overwrite
- dry run (without GitHub repository modification and OSS nexus upload)
Job setup must also follow this guide
Job parameters
This project is parameterized: checked
Name | Type | Default | Description |
---|---|---|---|
RELEASE_VERSION | String | Version to release. Default value is from POM snapshot. | |
NEXT_VERSION | String | Next snapshot version to set (e.g. 1.2.3-SNAPSHOT). Default value is RELEASE_VERSION with last component incremented by 1. | |
BRANCH | String | master | Branch to release. Default value is master. |
DRY_RUN | Boolean | false | Do not publish artifacts to OSSRH and code changes to GitHub. |
OVERWRITE | Boolean | false | Overwrite existing version in git and OSSRH staging repositories. |
Shell script
Job Environment
Job is being executed by bash. Specific settings for Java build tools in new Jenkins environment:
#!/bin/bash -ex TOOLS_PREFIX='/opt/tools' JAVA_PREFIX="${TOOLS_PREFIX}/java/openjdk" MVN_HOME="${TOOLS_PREFIX}/apache-maven/latest" JAVA_HOME="${JAVA_PREFIX}/jdk-11/latest" PATH="${MVN_HOME}/bin:${JAVA_HOME}/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
Input Parameters Processing
RELEASE_VERSION and NEXT_VERSION values can be empty. Following code replaces empty values with proper values:
- RELEASE_VERSION: version number from current snapshot version string
- NEXT_VERSION: RELEASE_VERSION with latest version component incremented by 1 and
-SNAPSHOT
suffix
Release tag name is also prepared.
# Maven plugins VERSIONS_PLUGIN='org.codehaus.mojo:versions-maven-plugin:2.7' HELP_PLUGIN='org.apache.maven.plugins:maven-help-plugin:3.1.0' # 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 -Pstaging -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 # Bash specific code 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
Git and Build Environment Preparation
If OVERWRITE argument is active (true), remote release branch and tag names are deleted.
If DRY_RUN argument is active (true), deploy:deploy
argument won't be passed to maven.
Old local release branch and tag are always deleted if exist and local release branch is initialized to store all code changes related to this release.
GitHub bot name and e-mail are set in git configuration.
if [ ${DRY_RUN} = 'true' ]; then echo '-[ Dry run turned on ]----------------------------------------------------------' MVN_DEPLOY_ARGS='' echo '-[ Skipping GitHub branch and tag checks ]--------------------------------------' else MVN_DEPLOY_ARGS='nexus-staging:deploy' GIT_ORIGIN=`git remote` echo '-[ Prepare branch ]-------------------------------------------------------------' 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 ${GIT_ORIGIN} "${RELEASE_VERSION}" && true else echo "Error: ${GIT_ORIGIN}/${RELEASE_VERSION} branch already exists" exit 1 fi fi echo '-[ Release tag cleanup ]--------------------------------------------------------' if [[ -n `git ls-remote --tags ${GIT_ORIGIN} | grep "${RELEASE_TAG}"` ]]; then if [ "${OVERWRITE}" = 'true' ]; then echo "${RELEASE_TAG} tag already exists, deleting" git push --delete ${GIT_ORIGIN} "${RELEASE_TAG}" && true else echo "Error: ${RELEASE_TAG} tag already exists" exit 1 fi fi fi # Always delete local branch if exists git branch --delete "${RELEASE_VERSION}" && true git checkout -b ${RELEASE_VERSION} # Always delete local tag if exists git tag --delete "${RELEASE_TAG}" && true # Setup jaxb-impl-bot account information git config --global user.email "jaxb-impl-bot@eclipse.org" git config --global user.name "Eclipse JAXBimpl Bot"
Workaround: GPG initialization
GPG setup is missing in Docker image and GPG keys are passed in KEYRING environment variables. Content of this variable must be processed and stored into GPG key store.
# Workaround: GPG initialization gpg --batch --import ${KEYRING} for fpr in $(gpg --list-keys --with-colons | awk -F: '/fpr:/ {print $10}' | sort -u); do echo -e "5\ny\n" | gpg --batch --command-fd 0 --expert --edit-key $fpr trust; done
Set Release Version
Project Group ID and Artifact ID values are retrieved from maven project (pom.xml
). Those values are used in git commit messages and nexus deployments description.
Release version is set in maven project (pom.xml
).
Updated project is stored in git release branch with corresponding message.
${VERSIONS_PLUGIN}:update-parent
is not required to update project versions in most cases so you may remove it from both version updating maven calls. But there are exceptions like jaxb-ri or metro-jax-ws with boms
where parent must be updated too.
# Project identifiers ARTIFACT_ID=$(mvn -B ${HELP_PLUGIN}:evaluate -Dexpression=project.artifactId -Pstaging | grep -Ev '(^\[)') GROUP_ID=$(mvn -B ${HELP_PLUGIN}:evaluate -Dexpression=project.groupId -Pstaging | grep -Ev '(^\[)') STAGING_DESC="${GROUP_ID}:${ARTIFACT_ID}:${RELEASE_VERSION}" STAGING_KEY=$(echo ${STAGING_DESC} | sed -e 's/\./\\\./g')
echo '-[ Set release version ]--------------------------------------------------------' # Set release version mvn -U -C -B -Pstaging \ -DnewVersion="${RELEASE_VERSION}" -DparentVersion="${RELEASE_VERSION}" \ -DprocessAllModules=true -DgenerateBackupPoms=false \ clean ${VERSIONS_PLUGIN}:set ${VERSIONS_PLUGIN}:update-parent echo '-[ Commit modified pom.xml files ]----------------------------------------------' POM_FILES=`git status | grep -E 'modified:.*pom\.xml' | sed -e 's/[[:space:]][[:space:]]*modified:[[:space:]][[:space:]]*//'` git add ${POM_FILES} && \ git commit -m "Prepare release ${GROUP_ID}:${ARTIFACT_ID}:${RELEASE_VERSION}"
Build and Deploy Artifacts
Old Nexus deployments with the same description groupId:artifactId:version
are dropped.
All artifacts are built and deployed to the staging repository.
Code with release versions is tagged with release tag.
This maven task requires specific settings.xml
file with GPG setup.
Profile oss-release
is defined in parent POM. It contains setup for packaging sources and javadoc and specific setup for GPG signing plugin (--pinentry-mode loopback
). Minimal version of parent POM is 1.0.5
.
Project's pom.xml must define versions for the following plugins:
- maven-enforcer-plugin
- maven-source-plugin
- maven-javadoc-plugin
- maven-gpg-plugin
echo '-[ Drop old staging repository deployments ]------------------------------------' for staging_key in $(mvn -B nexus-staging:rc-list -Pstaging | egrep "^\[INFO\] [A-Z,a-z,-]+-[0-9]+\s+[A-Z]+\s+${STAGING_KEY}" | awk '{print $2}'); do echo "Repository ID: ${staging_key}" mvn -U -C -B -Pstaging \ -DstagingRepositoryId="${staging_key}" \ nexus-staging::rc-drop done echo '-[ Deploy artifacts to staging repository ]-------------------------------------' mvn -U -C -B -Poss-release,staging \ -DskipTests -Ddoclint=none \ -DstagingDescription="${STAGING_DESC}" \ clean package source:jar javadoc:jar gpg:sign install:install ${MVN_DEPLOY_ARGS} echo '-[ Tag release ]----------------------------------------------------------------' git tag "${RELEASE_TAG}" -m "Release ${GROUP_ID}:${ARTIFACT_ID}:${RELEASE_VERSION}"
Set Next Development Cycle Version
Next development cycle SNAPSHOT version is set in maven project (pom.xml
).
Updated project is stored in git release branch with corresponding message.
echo '-[ Set next snapshot version ]--------------------------------------------------' mvn -U -C -B -Pstaging \ -DnewVersion="${NEXT_VERSION}" -DparentVersion="${NEXT_VERSION}" \ -DprocessAllModules=true -DgenerateBackupPoms=false \ clean ${VERSIONS_PLUGIN}:set ${VERSIONS_PLUGIN}:update-parent echo '-[ Commit modified pom.xml files ]----------------------------------------------' POM_FILES=`git status | grep -E 'modified:.*pom\.xml' | sed -e 's/[[:space:]][[:space:]]*modified:[[:space:]][[:space:]]*//'` git add ${POM_FILES} && \ git commit -m "Prepare next development cycle for ${NEXT_VERSION}"
NOTE: Once you're committed to the release, this release branch should be merged into master and deleted. This will move master to the next snapshot version and prepare it for future development. For example:
$ git pull -r $ git merge origin/1.2.3-RELEASE $ git push origin master $ git branch -D 1.2.3-RELEASE # deletes local branch, in case it exists $ git push origin :1.2.3-RELEASE # deletes remote branch
Update Git Repository
If DRY_RUN argument is not active (false), release branch and tag will be pushed to GitHub.
if [ ${DRY_RUN} = 'true' ]; then echo '-[ Skipping GitHub update ]-----------------------------------------------------' else echo '-[ Push branch and tag to GitHub ]----------------------------------------------' git push ${GIT_ORIGIN} "${RELEASE_VERSION}" git push ${GIT_ORIGIN} "${RELEASE_TAG}" fi
Project pom.xml in a Subdirectory
Previous script will work only when pom.xml
is in top level directory (WORKSPACE
) of the Jenkins job. Here is script modified for top level pom.xml in a subdirectory:
#!/bin/bash -ex TOOLS_PREFIX='/opt/tools' JAVA_PREFIX="${TOOLS_PREFIX}/java/openjdk" MVN_HOME="${TOOLS_PREFIX}/apache-maven/latest" JAVA_HOME="${JAVA_PREFIX}/jdk-11/latest" PATH="${MVN_HOME}/bin:${JAVA_HOME}/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" # Maven plugins VERSIONS_PLUGIN='org.codehaus.mojo:versions-maven-plugin:2.7' HELP_PLUGIN='org.apache.maven.plugins:maven-help-plugin:3.1.0' # Directory with project top level pom.xml BUILD_DIR="${WORKSPACE}/jaxws-ri" cd ${BUILD_DIR} # 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 -Pstaging -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 # Bash specific code 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_DEPLOY_ARGS='' echo '-[ Skipping GitHub branch and tag checks ]--------------------------------------' else MVN_DEPLOY_ARGS='nexus-staging:deploy' GIT_ORIGIN=`git remote` echo '-[ Prepare branch ]-------------------------------------------------------------' 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 ${GIT_ORIGIN} "${RELEASE_VERSION}" && true else echo "Error: ${GIT_ORIGIN}/${RELEASE_VERSION} branch already exists" exit 1 fi fi echo '-[ Release tag cleanup ]--------------------------------------------------------' if [[ -n `git ls-remote --tags ${GIT_ORIGIN} | grep "${RELEASE_TAG}"` ]]; then if [ "${OVERWRITE}" = 'true' ]; then echo "${RELEASE_TAG} tag already exists, deleting" git push --delete ${GIT_ORIGIN} "${RELEASE_TAG}" && true else echo "Error: ${RELEASE_TAG} tag already exists" exit 1 fi fi fi cd ${WORKSPACE} # Always delete local branch if exists git branch --delete "${RELEASE_VERSION}" && true git checkout -b ${RELEASE_VERSION} # Always delete local tag if exists git tag --delete "${RELEASE_TAG}" && true # Setup jaxb-impl-bot account information git config --global user.email "jaxb-impl-bot@eclipse.org" git config --global user.name "Eclipse JAXBimpl Bot" # Workaround: GPG initialization gpg --batch --import ${KEYRING} for fpr in $(gpg --list-keys --with-colons | awk -F: '/fpr:/ {print $10}' | sort -u); do echo -e "5\ny\n" | gpg --batch --command-fd 0 --expert --edit-key $fpr trust; done cd ${BUILD_DIR} # Project identifiers ARTIFACT_ID=$(mvn -B ${HELP_PLUGIN}:evaluate -Dexpression=project.artifactId -Pstaging | grep -Ev '(^\[)') GROUP_ID=$(mvn -B ${HELP_PLUGIN}:evaluate -Dexpression=project.groupId -Pstaging | grep -Ev '(^\[)') STAGING_DESC="${GROUP_ID}:${ARTIFACT_ID}:${RELEASE_VERSION}" STAGING_KEY=$(echo ${STAGING_DESC} | sed -e 's/\./\\\./g') echo '-[ Set release version ]--------------------------------------------------------' # Set release version mvn -U -C -B -Pstaging \ -DnewVersion="${RELEASE_VERSION}" -DparentVersion="${RELEASE_VERSION}" \ -DprocessAllModules=true -DgenerateBackupPoms=false \ clean ${VERSIONS_PLUGIN}:set ${VERSIONS_PLUGIN}:update-parent cd ${WORKSPACE} echo '-[ Commit modified pom.xml files ]----------------------------------------------' POM_FILES=`git status | grep -E 'modified:.*pom\.xml' | sed -e 's/[[:space:]][[:space:]]*modified:[[:space:]][[:space:]]*//'` git add ${POM_FILES} && \ git commit -m "Prepare release ${GROUP_ID}:${ARTIFACT_ID}:${RELEASE_VERSION}" cd ${BUILD_DIR} echo '-[ Drop old staging repository deployments ]------------------------------------' for staging_key in $(mvn -B nexus-staging:rc-list -Pstaging | egrep "^\[INFO\] [A-Z,a-z,-]+-[0-9]+\s+[A-Z]+\s+${STAGING_KEY}" | awk '{print $2}'); do echo "Repository ID: ${staging_key}" mvn -U -C -B -Pstaging \ -DstagingRepositoryId="${staging_key}" \ nexus-staging::rc-drop done echo '-[ Deploy artifacts to staging repository ]-------------------------------------' mvn -U -C -B -Poss-release,staging \ -DskipTests -Ddoclint=none \ -DstagingDescription="${STAGING_DESC}" \ clean package source:jar javadoc:jar gpg:sign install:install ${MVN_DEPLOY_ARGS} cd ${WORKSPACE} echo '-[ Tag release ]----------------------------------------------------------------' git tag "${RELEASE_TAG}" -m "Release ${GROUP_ID}:${ARTIFACT_ID}:${RELEASE_VERSION}" cd ${BUILD_DIR} echo '-[ Set next snapshot version ]--------------------------------------------------' mvn -U -C -B -Pstaging \ -DnewVersion="${NEXT_VERSION}" -DparentVersion="${NEXT_VERSION}" \ -DprocessAllModules=true -DgenerateBackupPoms=false \ clean ${VERSIONS_PLUGIN}:set ${VERSIONS_PLUGIN}:update-parent cd ${WORKSPACE} echo '-[ Commit modified pom.xml files ]----------------------------------------------' POM_FILES=`git status | grep -E 'modified:.*pom\.xml' | sed -e 's/[[:space:]][[:space:]]*modified:[[:space:]][[:space:]]*//'` git add ${POM_FILES} && \ git commit -m "Prepare next development cycle for ${NEXT_VERSION}" if [ ${DRY_RUN} = 'true' ]; then echo '-[ Skipping GitHub update ]-----------------------------------------------------' else echo '-[ Push branch and tag to GitHub ]----------------------------------------------' git push ${GIT_ORIGIN} "${RELEASE_VERSION}" git push ${GIT_ORIGIN} "${RELEASE_TAG}" fi