blob: ad2f1678d27068cce849a0a72367ea29f42972f1 [file] [log] [blame]
#!/usr/bin/env groovy
/*
* Copyright (c) 2024 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* This Source Code may also be made available under the following Secondary
* Licenses when the conditions for such availability set forth in the
* Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
* version 2 with the GNU Classpath Exception, which is available at
* https://www.gnu.org/software/classpath/license.html.
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
*/
/**
* Release script for Jakarta EE10 Jersey versions
* Release branch is 3.1
*
* Input Parameters:
* RELEASE_VERSION - type: String
* - example: 3.1.6
* - Description: mandatory release version. Later is being published to staging/central.
* NEXT_VERSION - type: String
* - example: 3.1.99-SNAPSHOT
* - Description: mandatory next developing version will be committed in to the release branch and later
* merged into the original release branch for further developing.
* BRANCH - type: Choice Parameter
* - values: 3.1
* - Description: Original release branch from which the codebase is being checked out
* DRY_RUN - type: Boolean
* - Description: if checked nothing is really committed to Git nor published to the staging
* OVERWRITE - type: Boolean
* - Description: if checked allows replacing of the previously published RELEASE_VERSION of Jersey
*
*/
#!/usr/bin/env groovy
node {
def MVN_HOME = tool name: 'apache-maven-latest', type: 'maven'
def HELP_PLUGIN = 'org.apache.maven.plugins:maven-help-plugin:2.1.1'
def TARGET = 'package javadoc:jar gpg:sign install:install'
def DEPLOY_TARGET = ''
def RELEASE_VERSION = RELEASE_VERSION
def NEXT_VERSION = NEXT_VERSION
def RELEASE_TAG = ''
def NEW_RELEASE_BRANCH = ''
def OVERWRITE = OVERWRITE
def PROJECT_NAME = 'Jersey'
def LOGIN = 'jersey-bot'
def EMAIL = 'jersey-bot@eclipse.org'
def REPO = 'git@github.com:eclipse-ee4j/jersey.git'
def SECRET_FILE_ID = 'secret-subkeys.asc'
def CREDENTIALS_ID = 'github-bot-ssh'
def GIT_ORIGIN = 'origin'
def RELEASE_FOLDER = env.WORKSPACE
def RELEASE_BRANCH = BRANCH
def STAGING_NAME_PATTERN = 'orgglassfishjersey-[0-9]+'
def STAGING_NAME = ''
def STAGING_PREV_NAME = ''
def STAGING_OPEN_NAME = ''
def STAGING_DESC = 'org.glassfish.jersey:' + RELEASE_VERSION
def STAGING_BOM_DESC = 'org.glassfish.jersey.bom:' + RELEASE_VERSION
def STAGING_PROFILE_ID = '70fa3a107a8918'
def MULTIRELEASE_MODULES = ':jersey-wadl-doclet,:jersey-spring6,:jersey-helidon-connector,:jersey-jetty-connector,:jersey-jetty-http2-connector,:jersey-container-jetty-http,:jersey-container-jetty-http2,:jersey-test-framework-provider-jetty,:jersey-test-framework-provider-jetty-http2'
def JDK_11_HOME = tool name: 'openjdk-jdk11-latest', type: 'jdk'
//def JDK_12_HOME = tool name: 'openjdk-jdk12-latest', type: 'jdk'
def JDK_21_HOME = tool name: 'openjdk-jdk21-latest', type: 'jdk'
//def JDK_8_HOME = tool name: 'oracle-jdk8-latest', type: 'jdk'
env.JAVA_HOME = JDK_11_HOME
env.PATH = "${env.JAVA_HOME}/bin:${env.PATH}:${MVN_HOME}/bin"
sh 'java -version'
stage('Fetch from git') {
git(branch: RELEASE_BRANCH, credentialsId: CREDENTIALS_ID, url: REPO)
}
stage('Prepare environment') {
dir(RELEASE_FOLDER) {
//# Check whether top level pom.xml contains SNAPSHOT version
if (!sh(returnStdout: true, script: "grep '<version>' pom.xml | grep 'SNAPSHOT'")?.trim()) {
error('-[ Missing SNAPSHOT version in POM! ]-------------------------------------------')
}
//# Compute release versions
def SNAPSHOT_VERSION = sh(returnStdout: true, script: 'mvn -q -Dexec.executable="echo" -Dexec.args=\'${project.version}\' --non-recursive exec:exec -Pstaging').trim()
if (!RELEASE_VERSION?.trim()) {
if (!SNAPSHOT_VERSION?.trim()) {
error('-[ Missing required snapshot version number! ]----------------------------------')
} else {
def versionTokens = SNAPSHOT_VERSION.split('-')
RELEASE_VERSION = versionTokens[0]
}
}
if (!NEXT_VERSION?.trim()) {
def (MAJOR_VERSION, MINOR_VERSION) = RELEASE_VERSION.tokenize('.')
def NEXT_MINOR_VERSION = (MINOR_VERSION as Integer) + 1
NEXT_VERSION = MAJOR_VERSION + '.' + NEXT_MINOR_VERSION + '-SNAPSHOT'
}
RELEASE_TAG = RELEASE_VERSION
NEW_RELEASE_BRANCH = RELEASE_VERSION+'-BRANCH'
echo "Current version: ${SNAPSHOT_VERSION}"
echo "Release version: ${RELEASE_VERSION}"
echo "Next version: ${NEXT_VERSION}"
echo "Release tag: ${RELEASE_TAG}"
echo "Release branch: ${NEW_RELEASE_BRANCH}"
if (!SNAPSHOT_VERSION?.trim() || !RELEASE_VERSION?.trim() || !NEXT_VERSION?.trim()) {
error '-[ Missing required version numbers! ]------------------------------------------'
}
if (DRY_RUN == 'true') {
echo '-[ Dry run turned on ]----------------------------------------------------------'
//TARGET = 'install'
} else {
DEPLOY_TARGET = ' deploy:deploy'
}
echo '-[ Configure git user ]--------------------------------------------------------'
sh "git config --local user.email \"${EMAIL}\""
sh "git config --local user.name \"$LOGIN\""
}
}
stage('Prepare GPG') {
withCredentials([file(credentialsId: SECRET_FILE_ID, variable: 'KEYRING')]) {
//# Workaround: GPG initialization
sh("gpg --batch --import ${KEYRING}")
sh '''
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
'''
}
}
stage('Prepare branch') {
echo '-[ Prepare branch ]-------------------------------------------------------------'
echo '-[ Switching to release branch ]-------------------------------------------------'
sh """
git checkout ${GIT_ORIGIN}/${RELEASE_BRANCH} && true
git reset --hard ${GIT_ORIGIN}/${RELEASE_BRANCH} && true
git checkout -B ${NEW_RELEASE_BRANCH}
"""
echo '-[ Release tag cleanup ]--------------------------------------------------------'
def TAG_NAME = sh(returnStdout: true, script: "git tag | grep ${RELEASE_TAG}\$ || true").trim()
if (RELEASE_TAG == TAG_NAME) {
if (OVERWRITE == 'true') {
echo "${RELEASE_TAG} tag already exists, deleting"
sshagent([CREDENTIALS_ID]) {
sh "git push --delete origin ${RELEASE_TAG} && true"
}
} else {
error "${RELEASE_TAG} tag already exists"
}
//# Always delete local tag if exists
sh """
git tag --delete ${RELEASE_TAG} && true
"""
}
sh '''
sed -i 's|<suppress files="generated" checks=".*"/>|<suppress files="generated" checks=".*"/><suppress files="unpacked-src" checks=".*"/>|g' etc/config/checkstyle-suppressions.xml
'''
}
stage('Check previous stagings') {
if (DRY_RUN == 'true') {
echo DRY_RUN + ' ------'
} else {
if (OVERWRITE == 'true') {
STAGING_PREV_NAME = sh(returnStdout: true,
script: "mvn -B --non-recursive -Pstaging nexus-staging:rc-list | awk '/\\[INFO] $STAGING_NAME_PATTERN[ ]+CLOSED[ ]+$STAGING_DESC[ ]*\$/ {if(a){a = \$2\",\"a} else{a = \$2}}END{print a}'").trim()
echo 'Previously closed staging name: ' + STAGING_PREV_NAME
}
STAGING_OPEN_NAME = sh(returnStdout: true,
script: "mvn -B --non-recursive -Pstaging nexus-staging:rc-list | awk '/$STAGING_NAME_PATTERN OPEN / {if(a){a = \$2\",\"a} else{a = \$2}}END{print a}'").trim()
if (!STAGING_OPEN_NAME?.trim()) {
echo 'No currently open stagings'
} else {
echo 'Currently open redundand staging: ' + STAGING_OPEN_NAME + ', immediately closing'
sh """
OPEN_STAGINGS=${STAGING_OPEN_NAME}
mvn -B -q -Pstaging nexus-staging:rc-drop -DstagingRepositoryId=\${OPEN_STAGINGS}
"""
}
}
}
/*
stage('Open new staging') {
if (DRY_RUN == 'true') {
echo DRY_RUN + ' ------'
} else {
STAGING_NAME = sh(returnStdout: true,
script: "mvn -B --non-recursive -Pstaging -DstagingProfileId=${STAGING_PROFILE_ID} -DstagingDescription=${STAGING_DESC} nexus-staging:rc-open | awk '/\\[INFO] Opened / {print \$3}'").trim()
echo 'New staging name: '+STAGING_NAME
}
}*/
stage("Build ${PROJECT_NAME}") {
echo env.JAVA_HOME
echo '-[ Run maven release ]---------------------------------------------------------'
echo '-[ Set Release version ]-------------------------------------------------------'
sh """
cd ${RELEASE_FOLDER}
mvn -q -B -V -Pstaging versions:set -DnewVersion=${RELEASE_VERSION} -DgenerateBackupPoms=false
mvn -q -B -V -Pstaging versions:set -DnewVersion=${RELEASE_VERSION} -DgenerateBackupPoms=false -f bom/pom.xml
"""
echo '-[ Update Copyright years ]----------------------------------------------------'
sh '''#!/bin/bash -e
export CURRENT_YEAR=`date '+%Y'`
export SED_CMD_LINE='sed -i "s#, 20.. Oracle and/or its affiliates#, ${CURRENT_YEAR} Oracle and/or its affiliates#g"'
git status --porcelain --untracked-files=no > modified_pom.log
cp modified_pom.log list_of_poms.txt
sed -i "s| M |$SED_CMD_LINE |g" modified_pom.log
sed -i "s| M ||g" list_of_poms.txt
bash modified_pom.log
echo ${CURRENT_YEAR} current year
while IFS= read -r path_to_pom
do
export CP_YEAR=`grep -o 'Copyright (c) 20.. Oracle and/or its affiliates' ${path_to_pom} | awk '{print $3}'`
[[ -z ${CP_YEAR} ]] && CP_YEAR=${CURRENT_YEAR} || echo ${CP_YEAR}
[[ ${CP_YEAR} == ${CURRENT_YEAR} ]] || ( sed -i "s#Copyright (c) ${CP_YEAR} Oracle and/or its affiliates#Copyright (c) ${CP_YEAR}, ${CURRENT_YEAR} Oracle and/or its affiliates#g" ${path_to_pom} ; echo ${path_to_pom} )
unset CP_YEAR
done < "list_of_poms.txt"
'''
echo '-[ Run release build ]---------------------------------------------------------'
dir(RELEASE_FOLDER) {
//env.JAVA_HOME = JDK_12_HOME
//sh 'mvn clean install -am -Pstaging -pl :jersey-wadl-doclet -DskipTests -B -q -V -Djersey.version=${RELEASE_VERSION}'
env.JAVA_HOME = JDK_21_HOME
sh "mvn clean install -B -q -V -DskipTests -am -Pstaging -Djersey.version=${RELEASE_VERSION} --projects ${MULTIRELEASE_MODULES}"
env.JAVA_HOME = JDK_11_HOME
//
sh "mvn -q -B -V -Djersey.version=${RELEASE_VERSION} -DskipTests -Ddoclint=none -Dadditionalparam='-Xdoclint:none' " +
" -Poss-release,staging -U -C ${TARGET} ${DEPLOY_TARGET}"
//sh "mvn -Poss-release,staging -pl :jersey-wadl-doclet -am install gpg:sign ${DEPLOY_TARGET} -B -q -V -DskipTests -Djersey.version=${RELEASE_VERSION}"
}
}
stage('Prepare release') {
sh '''
git checkout -- etc/config/checkstyle-suppressions.xml
'''
echo '-[ Perform release commit to git ]---------------------------------------------'
sh "git commit -a -m ${RELEASE_VERSION}"
sh "git tag -m ${RELEASE_TAG} -a ${RELEASE_TAG}"
echo '-[ Set next snapshot version ]-------------------------------------------------'
dir(RELEASE_FOLDER) {
sh """
mvn -q -B -Pstaging -Djersey.version=${RELEASE_VERSION} versions:set -DnewVersion=${NEXT_VERSION} -DgenerateBackupPoms=false
mvn -q -B -Pstaging -Djersey.version=${RELEASE_VERSION} versions:set -DnewVersion=${NEXT_VERSION} -DgenerateBackupPoms=false -f bom/pom.xml
"""
}
echo '-[ Perform commit to git ]-----------------------------------------------------'
sh "git commit -a -m ${NEXT_VERSION}"
}
stage('Publish release') {
if (DRY_RUN == 'true') {
echo '-[ Prepared branch ]----------------------------------------------------------'
sh "git branch --list ${NEW_RELEASE_BRANCH}"
echo '-[ Prepared tag ]-------------------------------------------------------------'
sh "git tag --list ${NEW_RELEASE_BRANCH}"
echo '-[ Prepared commits ]---------------------------------------------------------'
sh 'git log -n 5'
sshagent([CREDENTIALS_ID]) {
sh "git push ${GIT_ORIGIN} ${NEW_RELEASE_BRANCH} --dry-run"
}
return
} else {
sshagent([CREDENTIALS_ID]) {
sh "git push -f ${GIT_ORIGIN} ${NEW_RELEASE_BRANCH} --follow-tags"
}
}
}
stage('Find related staging') {
if (DRY_RUN != 'true') {
if (!STAGING_NAME?.trim()) {
try {
STAGING_NAME =
sh(returnStdout: true,
script: "mvn -Djersey.version=${RELEASE_VERSION} -B --non-recursive -Pstaging nexus-staging:rc-list | awk '/$STAGING_NAME_PATTERN OPEN / {if(a){a = \$2\",\"a} else{a = \$2}}END{print a}'"
).trim()
} catch (Error err) {
currentBuild.result = 'UNSTABLE'
}
}
echo 'Staging name: ' + STAGING_NAME
} else {
echo 'DRY_RUN'
}
}
stage('Close released staging') {
if (!STAGING_NAME?.trim()) {
echo 'Nothing to be closed'
} else {
sh("mvn -B -q -Pstaging -Djersey.version=${RELEASE_VERSION} nexus-staging:rc-close -DstagingRepositoryId=${STAGING_NAME} -DstagingDescription='${STAGING_DESC}'")
}
}
stage('Drop redundant staging') {
if (!STAGING_PREV_NAME?.trim()) {
echo 'Nothing to be dropped'
} else {
try {
sh("""
OPEN_STAGINGS=${STAGING_PREV_NAME}
mvn -Djersey.version=${RELEASE_VERSION} -B -q -Pstaging nexus-staging:rc-drop -DstagingRepositoryId=\${OPEN_STAGINGS}
""")
} catch (Error err) {
currentBuild.result = 'UNSTABLE'
}
}
}
}