# ========================================================================================= # Copyright (C) 2021 Orange & contributors # # This program is free software; you can redistribute it and/or modify it under the terms # of the GNU Lesser General Public License as published by the Free Software Foundation; # either version 3 of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; # without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # See the GNU Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public License along with this # program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth # Floor, Boston, MA 02110-1301, USA. # ========================================================================================= # default workflow rules workflow: rules: # exclude merge requests - if: $CI_MERGE_REQUEST_ID when: never - when: always variables: # variabilized tracking image TBC_TRACKING_IMAGE: "$CI_REGISTRY/to-be-continuous/tools/tracking:master" # Default Maven project root directory MAVEN_PROJECT_DIR: . # Maven image (can be overridden) MAVEN_IMAGE: "maven:latest" # default production ref name (pattern) PROD_REF: '/^(master|main)$/' # default integration ref name (pattern) INTEG_REF: '/^develop$/' # default configuration directory MAVEN_CFG_DIR: ".m2" # This will suppress any download for dependencies and plugins or upload messages which would clutter the console log. # `showDateTime` will show the passed time in milliseconds. You need to specify `--batch-mode` to make this work. MAVEN_OPTS: >- -Dhttps.protocols=TLSv1.2 -Dmaven.repo.local=${MAVEN_CFG_DIR}/repository -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=WARN -Dorg.slf4j.simpleLogger.showDateTime=true -Djava.awt.headless=true # As of Maven 3.3.0 instead of this you may define these options in `.mvn/maven.config` so the same config is used # when running from the command line. # `installAtEnd` and `deployAtEnd` are only effective with recent version of the corresponding plugins. MAVEN_CLI_OPTS: >- --batch-mode --errors --fail-at-end --show-version -DinstallAtEnd=true -DdeployAtEnd=true # Maven build arguments MAVEN_BUILD_ARGS: "org.jacoco:jacoco-maven-plugin:prepare-agent verify org.jacoco:jacoco-maven-plugin:report" # Sonar base analysis default args # see: https://docs.sonarqube.org/latest/analysis/analysis-parameters/ # default uses branch analysis: https://docs.sonarqube.org/latest/branches/overview/ SONAR_BASE_ARGS: >- sonar:sonar -Dsonar.host.url=${SONAR_URL} -Dsonar.links.homepage=${CI_PROJECT_URL} -Dsonar.links.ci=${CI_PROJECT_URL}/-/pipelines -Dsonar.links.issue=${CI_PROJECT_URL}/-/issues # Sonar GitLab plugin args # see: https://github.com/gabrie-allaigre/sonar-gitlab-plugin/#plugins-properties # -> enabled if $SONAR_GITLAB_TOKEN is set SONAR_GITLAB_ARGS: >- -Dsonar.gitlab.url=${CI_SERVER_URL} -Dsonar.gitlab.user_token=${SONAR_GITLAB_TOKEN} -Dsonar.gitlab.project_id=${CI_PROJECT_ID} -Dsonar.gitlab.commit_sha=${CI_COMMIT_SHA} -Dsonar.gitlab.ref_name=${CI_COMMIT_REF_NAME} # Dependency Check arguments MAVEN_DEPENDENCY_CHECK_ARGS: >- org.owasp:dependency-check-maven:aggregate -DretireJsAnalyzerEnabled=false -DassemblyAnalyzerEnabled=false -Dformats=HTML,JSON,XML # Maven deploy arguments MAVEN_DEPLOY_ARGS: "deploy -Dmaven.test.skip=true" # Maven release arguments MAVEN_RELEASE_ARGS: "release:prepare release:perform -Darguments=-Dmaven.test.skip=true" MAVEN_RELEASE_SCM_COMMENT_PREFIX: "[ci skip][maven-release-plugin]" stages: - build - test - publish .mvn-scripts: &mvn-scripts | # BEGSCRIPT set -e function log_info() { echo -e "[\\e[1;94mINFO\\e[0m] $*" } function log_warn() { echo -e "[\\e[1;93mWARN\\e[0m] $*" } function log_error() { echo -e "[\\e[1;91mERROR\\e[0m] $*" } function output_coverage() { jacoco_reports=$(find . -name "${JACOCO_CSV_REPORT:-jacoco.csv}") if [[ -n "$jacoco_reports" ]] then log_info "--- \\e[32mJaCoCo report(s) found\\e[0m (\\e[33;1m${jacoco_reports}\\e[0m): output" # shellcheck disable=SC2046,SC2086 awk -F',' '{ instructions += $4 + $5; covered += $5 } END { print covered"/"instructions " instructions covered"; print 100*covered/instructions "% covered" }' $(find . -name "${JACOCO_CSV_REPORT:-jacoco.csv}") else log_info "--- \\e[32mJaCoCo report(s) not found: skip" fi } function sonar_http_auth_args() { if [[ -n "$SONAR_AUTH_TOKEN" ]] then echo "$SONAR_AUTH_TOKEN:" elif [[ -n "$SONAR_LOGIN" ]] && [[ -n "$SONAR_PASSWORD" ]] then echo "$SONAR_LOGIN:$SONAR_PASSWORD" else echo "" fi } function sonar_autodetect_mr() { if [[ "$SONAR_BRANCH_ANALYSIS_DISABLED" == "true" ]] then log_info "Branch Analysis and Merge Request Analysis are disabled" return fi if [[ "$CI_MERGE_REQUEST_ID" ]] then # we are in an MR pipeline: no need to pass arguments as the SonarScanner for Maven will log_info "Merge Request pipeline detected: let Maven plugin handle..." return fi if [[ -n "$SONAR_GITLAB_TOKEN" ]] then curl -sS --header "PRIVATE-TOKEN: $SONAR_GITLAB_TOKEN" "$CI_API_V4_URL/projects/${CI_PROJECT_ID}/merge_requests?state=opened&source_branch=${CI_COMMIT_REF_NAME}" -o mr.json if [ "$(cat mr.json)" != "[]" ] then mr_title=$(sed -E 's/\[\{[^{]*"title":"([^"]*)".*/\1/g' < mr.json) mr_target=$(sed -E 's/\[\{[^{]*"target_branch":"([^"]*)".*/\1/g' < mr.json) mr_id=$(sed -E 's/\[\{[^{]*"iid":([0-9]+).*/\1/g' < mr.json) log_info "Merge Request \\e[33;1m$mr_title\\e[0m detected associated to this branch: trigger MR analysis..." export sonar_mr_args="-Dsonar.pullrequest.key=$mr_id -Dsonar.pullrequest.branch=${CI_COMMIT_REF_NAME} -Dsonar.pullrequest.base=$mr_target" else log_info "No Merge Request associated to this branch: trigger branch analysis..." export sonar_mr_args="-Dsonar.branch.name=${CI_COMMIT_REF_NAME}" fi else log_info "\$SONAR_GITLAB_TOKEN unset: trigger branch analysis..." export sonar_mr_args="-Dsonar.branch.name=${CI_COMMIT_REF_NAME}" fi } function sonar_quality_gate_check() { log_info "--- Waiting for Sonar analysis end..." taskId=$(grep ceTaskId target/sonar/report-task.txt | cut -c10-) curl -sS -k --user "$(sonar_http_auth_args)" "$SONAR_URL/api/ce/task?id=$taskId" -o analysis.json analysisStatus=$(grep --only-matching --extended-regexp "\"status\":\"[A-Z_-]+\"" analysis.json | awk -F: '{print $2}' | tr -d '"') while [ "$analysisStatus" == "IN_PROGRESS" ] || [ "$analysisStatus" == "PENDING" ]; do sleep 5s curl -sS -k --user "$(sonar_http_auth_args)" "$SONAR_URL/api/ce/task?id=$taskId" -o analysis.json analysisStatus=$(grep --only-matching --extended-regexp "\"status\":\"[A-Z_-]+\"" analysis.json | awk -F: '{print $2}' | tr -d '"') done # Check quality gate if [ "$analysisStatus" == "SUCCESS" ]; then analysisId=$(grep --only-matching --extended-regexp "\"analysisId\":\"[a-zA-Z0-9_-]+\"" analysis.json | awk -F: '{print $2}' | tr -d '"') qualityGateStatus=$(curl -sS -k --user "$(sonar_http_auth_args)" "$SONAR_URL/api/qualitygates/project_status?analysisId=$analysisId" | grep --only-matching --extended-regexp "{\"projectStatus\":{\"status\":\"[A-Z_]+\"" | awk -F: '{print $3}' | tr -d '"') if [ "$qualityGateStatus" == "ERROR" ]; then log_error "... quality gate FAILED" exit 1 else log_info "... quality gate SUCCEEDED" exit 0 fi else log_error "... Sonar analysis FAILED" exit 1 fi } function maybe_set_version_from_git() { if [[ -n "$MAVEN_RELEASE_VERSION_FROM_GIT" ]]; then # compute version as timestamp of latest commit cur_version="$(date -d "$(git log -n 1 --pretty=format:%ci)" "+%Y.%m.%d.%H%M%S")" log_info "--- setting project version from latest git commit: \\e[33;1m${cur_version}\\e[0m" # change version in pom # shellcheck disable=SC2086 mvn versions:set $MAVEN_CLI_OPTS $mvn_settings_opt $java_proxy_args -DgenerateBackupPoms=false -DnewVersion="$cur_version-SNAPSHOT" # git commit change git commit -am "[ci skip] Prepare release with $cur_version version" fi } function configure_scm_auth() { # shellcheck disable=SC2086 scm_url=$(mvn $MAVEN_CLI_OPTS $mvn_settings_opt $java_proxy_args org.apache.maven.plugins:maven-help-plugin:3.2.0:evaluate -Dexpression=project.scm.developerConnection -q -DforceStdout | tail -n 1) if [[ $scm_url == "scm:git:https"* ]]; then if [[ -n "${GIT_USERNAME}" ]] && [[ -n "${GIT_PASSWORD}" ]]; then log_info "--- using SCM credentials from env (\$GIT_USERNAME and \$GIT_PASSWORD)..." export scm_auth_args="-Dusername=${GIT_USERNAME} -Dpassword=${GIT_PASSWORD}" else log_error "--- project scm.developerConnection is using HTTPS protocol but no Git credentials are configured." log_error "--- Please specify the \$GIT_USERNAME and \$GIT_PASSWORD variables or change to SSH protocol with a SSH key." fi else # assume project is using SSH protocol if [[ -n "${GIT_PRIVATE_KEY}" ]]; then log_info "--- using Git SSH key from env (\$GIT_PRIVATE_KEY)..." mkdir -m 700 "${HOME}/.ssh" ssh-keyscan -H "${CI_SERVER_HOST}" >> ~/.ssh/known_hosts eval "$(ssh-agent -s)" # Handle file variable if [[ -f "${GIT_PRIVATE_KEY}" ]]; then tr -d '\r' < "${GIT_PRIVATE_KEY}" | ssh-add - else echo "${GIT_PRIVATE_KEY}" | tr -d '\r' | ssh-add - fi git config --global user.email "${GITLAB_USER_EMAIL}" git config --global user.name "${GITLAB_USER_LOGIN}" else log_error "--- project scm.developerConnection is using SSH protocol but no SSH key configured." log_error "--- Please either specify the \$GIT_PRIVATE_KEY variable or change to https protocol with username/password credentials." fi fi } function install_ca_certs() { certs=$1 if [[ -z "$certs" ]] then return fi # import in system if echo "$certs" >> /etc/ssl/certs/ca-certificates.crt then log_info "CA certificates imported in \\e[33;1m/etc/ssl/certs/ca-certificates.crt\\e[0m" fi if echo "$certs" >> /etc/ssl/cert.pem then log_info "CA certificates imported in \\e[33;1m/etc/ssl/cert.pem\\e[0m" fi # import in Java keystore (if keytool command found) if command -v keytool > /dev/null then # shellcheck disable=SC2046 javahome=${JAVA_HOME:-$(dirname $(readlink -f $(command -v java)))/..} # shellcheck disable=SC2086 keystore=${JAVA_KEYSTORE_PATH:-$(ls -1 $javahome/jre/lib/security/cacerts 2>/dev/null || ls -1 $javahome/lib/security/cacerts 2>/dev/null || echo "")} if [[ -f "$keystore" ]] then storepass=${JAVA_KEYSTORE_PASSWORD:-changeit} nb_certs=$(echo "$certs" | grep -c 'END CERTIFICATE') log_info "importing $nb_certs certificates in Java keystore \\e[33;1m$keystore\\e[0m..." for idx in $(seq 0 $((nb_certs - 1))) do # TODO: use keytool option -trustcacerts ? if echo "$certs" | awk "n==$idx { print }; /END CERTIFICATE/ { n++ }" | keytool -noprompt -import -alias "imported CA Cert $idx" -keystore "$keystore" -storepass "$storepass" then log_info "... CA certificate [$idx] successfully imported" else log_warn "... Failed importing CA certificate [$idx]: abort" return fi done else log_warn "Java keystore \\e[33;1m$keystore\\e[0m not found: could not import CA certificates" fi fi } function unscope_variables() { _scoped_vars=$(env | awk -F '=' "/^scoped__[a-zA-Z0-9_]+=/ {print \$1}" | sort) if [[ -z "$_scoped_vars" ]]; then return; fi log_info "Processing scoped variables..." for _scoped_var in $_scoped_vars do _fields=${_scoped_var//__/:} _condition=$(echo "$_fields" | cut -d: -f3) case "$_condition" in if) _not="";; ifnot) _not=1;; *) log_warn "... unrecognized condition \\e[1;91m$_condition\\e[0m in \\e[33;1m${_scoped_var}\\e[0m" continue ;; esac _target_var=$(echo "$_fields" | cut -d: -f2) _cond_var=$(echo "$_fields" | cut -d: -f4) _cond_val=$(eval echo "\$${_cond_var}") _test_op=$(echo "$_fields" | cut -d: -f5) case "$_test_op" in defined) if [[ -z "$_not" ]] && [[ -z "$_cond_val" ]]; then continue; elif [[ "$_not" ]] && [[ "$_cond_val" ]]; then continue; fi ;; equals|startswith|endswith|contains|in|equals_ic|startswith_ic|endswith_ic|contains_ic|in_ic) # comparison operator # sluggify actual value _cond_val=$(echo "$_cond_val" | tr '[:punct:]' '_') # retrieve comparison value _cmp_val_prefix="scoped__${_target_var}__${_condition}__${_cond_var}__${_test_op}__" _cmp_val=${_scoped_var#"$_cmp_val_prefix"} # manage 'ignore case' if [[ "$_test_op" == *_ic ]] then # lowercase everything _cond_val=$(echo "$_cond_val" | tr '[:upper:]' '[:lower:]') _cmp_val=$(echo "$_cmp_val" | tr '[:upper:]' '[:lower:]') fi case "$_test_op" in equals*) if [[ -z "$_not" ]] && [[ "$_cond_val" != "$_cmp_val" ]]; then continue; elif [[ "$_not" ]] && [[ "$_cond_val" == "$_cmp_val" ]]; then continue; fi ;; startswith*) if [[ -z "$_not" ]] && [[ "$_cond_val" != "$_cmp_val"* ]]; then continue; elif [[ "$_not" ]] && [[ "$_cond_val" == "$_cmp_val"* ]]; then continue; fi ;; endswith*) if [[ -z "$_not" ]] && [[ "$_cond_val" != *"$_cmp_val" ]]; then continue; elif [[ "$_not" ]] && [[ "$_cond_val" == *"$_cmp_val" ]]; then continue; fi ;; contains*) if [[ -z "$_not" ]] && [[ "$_cond_val" != *"$_cmp_val"* ]]; then continue; elif [[ "$_not" ]] && [[ "$_cond_val" == *"$_cmp_val"* ]]; then continue; fi ;; in*) if [[ -z "$_not" ]] && [[ "__${_cmp_val}__" != *"__${_cond_val}__"* ]]; then continue; elif [[ "$_not" ]] && [[ "__${_cmp_val}__" == *"__${_cond_val}__"* ]]; then continue; fi ;; esac ;; *) log_warn "... unrecognized test operator \\e[1;91m${_test_op}\\e[0m in \\e[33;1m${_scoped_var}\\e[0m" continue ;; esac # matches _val=$(eval echo "\$${_target_var}") log_info "... apply \\e[32m${_target_var}\\e[0m from \\e[32m\$${_scoped_var}\\e[0m${_val:+ (\\e[33;1moverwrite\\e[0m)}" _val=$(eval echo "\$${_scoped_var}") export "${_target_var}"="${_val}" done log_info "... done" } # builds the Java proxy options from Linux env (http_proxy, https_proxy, ftp_proxy and no_proxy) function eval_java_proxy_args() { # transform no_proxy into Java stype nonProxyHosts nph=$(echo "${no_proxy:-$NO_PROXY}" | sed -e 's/\s*//g' -e 's/^\./*./' -e 's/,\./,*./g' -e 's/,/|/g') java_proxy_args="$(java_proto_proxy_args http "${http_proxy:-$HTTP_PROXY}" "$nph") $(java_proto_proxy_args https "${https_proxy:-$HTTPS_PROXY}" "$nph") $(java_proto_proxy_args ftp "${ftp_proxy:-$FTP_PROXY}" "$nph")" export java_proxy_args if [[ "$java_proxy_args" ]] then log_info "Using Java proxy options (from env): \\e[33;1m$java_proxy_args\\e[0m" fi } function java_proto_proxy_args() { proto=$1 proxy=$2 non_proxy_hosts=$3 if [[ "$proxy" ]] then host_port=$(echo "$proxy" | cut -d'/' -f3) host=$(echo "$host_port" | cut -d':' -f1) port=$(echo "$host_port" | cut -s -d':' -f2) proto_proxy_args="-D$proto.proxyHost=$host -D$proto.proxyPort=${port:-80}" if [[ "$non_proxy_hosts" ]]; then proto_proxy_args="$proto_proxy_args -D$proto.nonProxyHosts=\"$non_proxy_hosts\""; fi echo "$proto_proxy_args" fi } # autodetects any Maven settings file in $MAVEN_CFG_DIR and builds the Java CLI option accordingly function eval_mvn_settings_opt() { if [[ -f "$MAVEN_CFG_DIR/settings.xml" ]] then log_info "Maven settings file found: \\e[33;1m$MAVEN_CFG_DIR/settings.xml\\e[0m" mvn_settings_opt="-s $MAVEN_CFG_DIR/settings.xml" fi } function perform_snapshot() { # shellcheck disable=SC2086 pom_version=$(mvn $MAVEN_CLI_OPTS $mvn_settings_opt $java_proxy_args org.apache.maven.plugins:maven-help-plugin:3.2.0:evaluate -Dexpression=project.version -q -DforceStdout | tail -n 1) case $pom_version in *-SNAPSHOT) log_info "Snapshot version for pom (\\e[33;1m${pom_version}\\e[0m): deploy" # shellcheck disable=SC2086 mvn $MAVEN_CLI_OPTS $mvn_settings_opt $java_proxy_args $MAVEN_DEPLOY_ARGS ;; *) log_info "Not snapshot version for pom (\\e[33;1m${pom_version}\\e[0m): skip" ;; esac } unscope_variables # ENDSCRIPT # Generic maven job .mvn-base: image: $MAVEN_IMAGE services: - name: "$TBC_TRACKING_IMAGE" command: ["--service", "maven", "2.3.0" ] before_script: - *mvn-scripts - install_ca_certs "${CUSTOM_CA_CERTS:-$DEFAULT_CA_CERTS}" - eval_java_proxy_args - eval_mvn_settings_opt - cd ${MAVEN_PROJECT_DIR} # Cache downloaded dependencies and plugins between builds. # To keep cache across branches add 'key: "$CI_JOB_NAME"' cache: key: "$CI_COMMIT_REF_SLUG-maven" paths: - ${MAVEN_CFG_DIR}/repository mvn-build: extends: .mvn-base stage: build script: - mvn ${TRACE+-X} $MAVEN_CLI_OPTS $mvn_settings_opt $java_proxy_args $MAVEN_BUILD_ARGS - output_coverage # code coverage RegEx coverage: '/^(\d+\.?\d*\%) covered$/' # keep build artifacts and JUnit reports artifacts: name: "$CI_JOB_NAME artifacts from $CI_PROJECT_NAME on $CI_COMMIT_REF_SLUG" expire_in: 1 day when: always reports: junit: - "${MAVEN_PROJECT_DIR}/**/target/*-reports/TEST-*.xml" paths: - "${MAVEN_PROJECT_DIR}/**/target" # Sonar job mvn-sonar: stage: test extends: .mvn-base variables: # Tells git to fetch all the branches of the project, required by the analysis task # see: https://docs.sonarqube.org/8.5/analysis/gitlab-cicd/#header-2 GIT_DEPTH: 0 script: - sonar_autodetect_mr - if [[ "$SONAR_GITLAB_TOKEN" ]]; then sonar_extra_args="$SONAR_GITLAB_ARGS"; fi - mvn ${TRACE+-Dsonar.verbose=true} $MAVEN_CLI_OPTS $mvn_settings_opt $java_proxy_args ${SONAR_AUTH_TOKEN+-Dsonar.login=$SONAR_AUTH_TOKEN} ${SONAR_LOGIN+-Dsonar.login=$SONAR_LOGIN} ${SONAR_PASSWORD+-Dsonar.password=$SONAR_PASSWORD} $SONAR_BASE_ARGS $sonar_extra_args $sonar_mr_args - if [[ "$SONAR_QUALITY_GATE_ENABLED" == "true" ]]; then sonar_quality_gate_check; fi rules: # exclude if $SONAR_URL not set - if: '$SONAR_URL == null || $SONAR_URL == ""' when: never # on tags: auto - if: $CI_COMMIT_TAG # on production or integration: auto - if: '$CI_COMMIT_REF_NAME =~ $PROD_REF || $CI_COMMIT_REF_NAME =~ $INTEG_REF' # else (non-production, non-integration branches): manual if $SONAR_AUTO_ON_DEV_DISABLED - if: '$SONAR_AUTO_ON_DEV_DISABLED == "true"' when: manual allow_failure: true # else: auto & allow failure - allow_failure: true mvn-dependency-check: extends: .mvn-base stage: test # force no dependency dependencies: [] script: - mvn ${TRACE+-X} $MAVEN_CLI_OPTS $mvn_settings_opt $java_proxy_args $MAVEN_DEPENDENCY_CHECK_ARGS rules: # on schedule: auto - if: '$CI_PIPELINE_SOURCE == "schedule"' allow_failure: true when: always # all other cases: manual & non-blocking - when: manual allow_failure: true artifacts: name: "$CI_JOB_NAME artifacts from $CI_PROJECT_NAME on $CI_COMMIT_REF_SLUG" expire_in: 1 day when: always paths: - "${MAVEN_PROJECT_DIR}/**/target/dependency-check-report.*" mvn-forbid-snapshot-dependencies: extends: .mvn-base stage: test script: - mvn ${TRACE+-X} $MAVEN_CLI_OPTS $mvn_settings_opt $java_proxy_args org.apache.maven.plugins:maven-enforcer-plugin:3.0.0:enforce -Drules=requireReleaseDeps rules: # exclude if disabled - if: '$MVN_FORBID_SNAPSHOT_DEPENDENCIES_DISABLED == "true"' when: never # on production or integration branches: auto - if: '$CI_COMMIT_REF_NAME =~ $PROD_REF || $CI_COMMIT_REF_NAME =~ $INTEG_REF' # else (feature branches): auto & non-blocking - allow_failure: true mvn-snapshot: extends: .mvn-base stage: publish script: - perform_snapshot rules: # on tags: never - if: $CI_COMMIT_TAG when: never # exclude unprotected ref if specified - if: '$MAVEN_DEPLOY_FROM_UNPROTECTED_DISABLED == "true" && $CI_COMMIT_REF_PROTECTED != "true"' when: never # else: if $MAVEN_DEPLOY_ENABLED is set - if: '$MAVEN_DEPLOY_ENABLED == "true"' mvn-release: extends: .mvn-base stage: publish before_script: - !reference [ .mvn-base, before_script ] - log_info "Preparing Git repository for release..." - git config --global user.name $GITLAB_USER_ID - git config --global user.email $GITLAB_USER_EMAIL - git checkout -B "$CI_COMMIT_REF_NAME" script: - configure_scm_auth - maybe_set_version_from_git - | if [ "${SEMREL_INFO_ON}" ] && [ "${MVN_SEMREL_RELEASE_DISABLED}" != "true" ] then if [ -z "${SEMREL_INFO_NEXT_VERSION}" ] then log_info "no new version to release" exit 0 else log_info "semantic-release info is activated, using computed next version for release \\e[1;94m${SEMREL_INFO_NEXT_VERSION}\\e[0m" semrel_args="-DreleaseVersion=${SEMREL_INFO_NEXT_VERSION}" fi fi - mvn ${TRACE+-X} $MAVEN_CLI_OPTS $mvn_settings_opt $java_proxy_args $scm_auth_args ${MAVEN_RELEASE_ARGS} ${semrel_args} -DscmCommentPrefix="$MAVEN_RELEASE_SCM_COMMENT_PREFIX" rules: # on production branch(es): manual & non-blocking if $MAVEN_DEPLOY_ENABLED is set - if: '$MAVEN_DEPLOY_ENABLED == "true" && $CI_COMMIT_REF_NAME =~ $PROD_REF' when: manual allow_failure: true # on integration branch(es): manual & non-blocking if $MAVEN_DEPLOY_ENABLED is set - if: '$MAVEN_DEPLOY_ENABLED == "true" && $CI_COMMIT_REF_NAME =~ $INTEG_REF' when: manual allow_failure: true