diff --git a/.jenkins/jenkins_pod.yml b/.jenkins/jenkins_pod.yml index f2d3a1b5961a8..7fccded0ef4b8 100644 --- a/.jenkins/jenkins_pod.yml +++ b/.jenkins/jenkins_pod.yml @@ -1,33 +1,54 @@ + apiVersion: v1 kind: Pod spec: + ## imagePullSecrets: - name: talend-registry + ## containers: - - name: main + ## + - name: docker-daemon # Container that hosts the Docker daemon/socket + image: artifactory.datapwn.com/docker-io-remote/docker:24.0.7-dind-rootless # Rootless versions + command: + - 'dockerd-entrypoint.sh' # Override entry point to add parameters + args: + - '--tls=false' # De-activate TLS (not possible in rootless mode) + env: + - name: DOCKER_TLS_CERTDIR # Don't generate the certificate since it's not used (faster startup) + value: "" + securityContext: + privileged: true # Needed to bootstrap the Docker image. as rootless, it uses a non-root user at startup + ### + - name: main # default container for jenkins job execution # 3.0.9-20220930152032 is the last root version of custom-builder - image: 'artifactory.datapwn.com/tlnd-docker-dev/talend/common/tsbi/custom-builder:3.0.9-20220930152032' + # If you use this pod you will be jenkins user + # TSBI customBuilder documentation: https://github.com/Talend/tsbi-images/blob/main/tsbi/custom-builder/README.md + image: 'artifactory.datapwn.com/tlnd-docker-dev/talend/common/tsbi/custom-builder:4.0.24-20241016140323' command: [ cat ] tty: true volumeMounts: [ - { name: efs-jenkins-component-runtime-m2, mountPath: /root/.m2/repository}, - { name: efs-jenkins-connectors-asdf, mountPath: /root/.asdf/installs, subPath: installs } + { name: efs-jenkins-component-runtime-m2-rootless, + mountPath: /home/jenkins/.m2/repository }, + { name: efs-jenkins-connectors-asdf-rootless, + mountPath: /home/jenkins/.asdf/installs}, ] - resources: {requests: {memory: 6G, cpu: '4.0'}, limits: {memory: 8G, cpu: '5.0'}} + resources: { requests: { memory: 5G, cpu: '2' } } env: - - name: DOCKER_HOST + - name: DOCKER_HOST # Points the Docker client to the socket hosted by the docker-daemon container (see below) value: tcp://localhost:2375 - - name: docker-daemon - image: artifactory.datapwn.com/docker-io-remote/docker:19.03.1-dind - env: - - name: DOCKER_TLS_CERTDIR - value: "" - securityContext: - privileged: true - volumes: - - name: efs-jenkins-component-runtime-m2 + readinessProbe: + exec: + command: + - docker + - info + initialDelaySeconds: 5 + periodSeconds: 5 + ## + volumes: # Persistent volumes stored under Amazon Elastic File System (efs) defined in flux + - name: efs-jenkins-component-runtime-m2-rootless persistentVolumeClaim: - claimName: efs-jenkins-component-runtime-m2 - - name: efs-jenkins-connectors-asdf + claimName: efs-jenkins-component-runtime-m2-rootless + - name: efs-jenkins-connectors-asdf-rootless persistentVolumeClaim: - claimName: efs-jenkins-connectors-asdf \ No newline at end of file + claimName: efs-jenkins-connectors-asdf-rootless diff --git a/.jenkins/scripts/docker_build.sh b/.jenkins/scripts/docker_build.sh index 2372b025eb67f..46b5cb8df3aa7 100755 --- a/.jenkins/scripts/docker_build.sh +++ b/.jenkins/scripts/docker_build.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash # -# Copyright (C) 2006-2024 Talend Inc. - www.talend.com +# Copyright (C) 2006-2025 Talend Inc. - www.talend.com # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -30,17 +30,21 @@ dockerBuild() { _IMAGE="${1}" printf ">> Building and push %s:%s\n" "{$_IMAGE}" "${_TAG}" if [[ ${_IS_LATEST} == 'true' ]]; then - printf ">>THe image will be tagged as LATEST\n" + printf ">>The image will be tagged as LATEST\n" fi + local skip_for_docker_build="-DskipTests -DskipITs -Dcheckstyle.skip -Denforcer.skip=true -Drat.skip -Dspotless.skip=true" + mvn package jib:build@build \ --file "images/${_IMAGE}-image/pom.xml" \ - --define docker.talend.image.tag="${_TAG}" + --define docker.talend.image.tag="${_TAG}" \ + $skip_for_docker_build if [[ ${_IS_LATEST} == 'true' ]]; then mvn package jib:build@build \ --file "images/${_IMAGE}-image/pom.xml" \ - --define docker.talend.image.tag=latest + --define docker.talend.image.tag=latest \ + $skip_for_docker_build fi } diff --git a/.jenkins/scripts/docker_login.sh b/.jenkins/scripts/docker_login.sh index 6cc6221487b6d..332daf2ba2aeb 100644 --- a/.jenkins/scripts/docker_login.sh +++ b/.jenkins/scripts/docker_login.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash # -# Copyright (C) 2006-2024 Talend Inc. - www.talend.com +# Copyright (C) 2006-2025 Talend Inc. - www.talend.com # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/.jenkins/scripts/git_login.sh b/.jenkins/scripts/git_login.sh deleted file mode 100644 index 18afde47d62c5..0000000000000 --- a/.jenkins/scripts/git_login.sh +++ /dev/null @@ -1,44 +0,0 @@ -#!/usr/bin/env bash -# -# Copyright (C) 2006-2024 Talend Inc. - www.talend.com -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -set -xe - -# Parameters: -# $1: github username -# $2: github password -main() { - local username="${1?Missing github username}" - local password="${2?Missing github password}" - - git config --global credential.username ${username} - git config --global credential.helper '!echo password=${password}; echo' - git config --global credential.name "jenkins-build" - - { - printf "machine github.com\n" - printf "login %s\n" "${username}" - printf "password %s\n" "${password}" - - printf "machine api.github.com\n" - printf "login %s\n" "${username}" - printf "password %s\n" "${password}" - } > ~/.netrc - - chmod 600 ~/.netrc -} - -main "$@" diff --git a/.jenkins/scripts/mvn-ossindex-audit.sh b/.jenkins/scripts/mvn-ossindex-audit.sh index c0f31994f5c58..ee5fd1aaa33b9 100644 --- a/.jenkins/scripts/mvn-ossindex-audit.sh +++ b/.jenkins/scripts/mvn-ossindex-audit.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash # -# Copyright (C) 2006-2024 Talend Inc. - www.talend.com +# Copyright (C) 2006-2025 Talend Inc. - www.talend.com # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -19,7 +19,7 @@ set -xe main() ( - mvn ossindex:audit-aggregate -pl '!bom' \ + mvn ossindex:audit-aggregate \ --define ossindex.fail=false \ --define ossindex.reportFile=target/audit.txt \ --settings .jenkins/settings.xml diff --git a/.jenkins/scripts/mvn_dependency_updates_report.sh b/.jenkins/scripts/mvn_dependency_updates_report.sh index 1fddc672840ce..63341b4179707 100644 --- a/.jenkins/scripts/mvn_dependency_updates_report.sh +++ b/.jenkins/scripts/mvn_dependency_updates_report.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash # -# Copyright (C) 2006-2024 Talend Inc. - www.talend.com +# Copyright (C) 2006-2025 Talend Inc. - www.talend.com # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -19,7 +19,8 @@ set -xe main() ( - mvn versions:dependency-updates-report versions:plugin-updates-report -pl '!bom' + mvn versions:dependency-updates-report versions:plugin-updates-report \ + --settings .jenkins/settings.xml ) diff --git a/.jenkins/scripts/mvn_sonar_branch.sh b/.jenkins/scripts/mvn_sonar_branch.sh deleted file mode 100644 index bf2488056510e..0000000000000 --- a/.jenkins/scripts/mvn_sonar_branch.sh +++ /dev/null @@ -1,42 +0,0 @@ -#!/usr/bin/env bash -# -# Copyright (C) 2006-2024 Talend Inc. - www.talend.com -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -set -xe - -# Execute sonar analysis -# $1: Sonar analyzed branch -# $@: the extra parameters to be used in the maven commands -main() ( - branch="${1?Missing branch name}"; shift - extraBuildParams=("$@") - - declare -a LIST_FILE_ARRAY=( $(find $(pwd) -type f -name 'jacoco.xml') ) - LIST_FILE=$(IFS=, ; echo "${LIST_FILE_ARRAY[*]}") - - # Why sonar plugin is not declared in pom.xml: https://blog.sonarsource.com/we-had-a-dream-mvn-sonarsonar - # TODO https://jira.talendforge.org/browse/TDI-48980 (CI: Reactivate Sonar cache) - mvn sonar:sonar \ - --define 'sonar.host.url=https://sonar-eks.datapwn.com' \ - --define "sonar.login=${SONAR_LOGIN}" \ - --define "sonar.password=${SONAR_PASSWORD}" \ - --define "sonar.branch.name=${branch}" \ - --define "sonar.coverage.jacoco.xmlReportPaths='${LIST_FILE}'" \ - --define "sonar.analysisCache.enabled=false" \ - "${extraBuildParams[@]}" -) - -main "$@" diff --git a/.jenkins/scripts/mvn_sonar_pr.sh b/.jenkins/scripts/mvn_sonar_pr.sh deleted file mode 100644 index d2eeb7362d6ff..0000000000000 --- a/.jenkins/scripts/mvn_sonar_pr.sh +++ /dev/null @@ -1,53 +0,0 @@ -#!/usr/bin/env bash -# -# Copyright (C) 2006-2024 Talend Inc. - www.talend.com -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -set -xe - -# Execute sonar analysis -# $1: Sonar analyzed branch -# $2: Sonar target branch for compare -# $3: PR id -# $@: the extra parameters to be used in the maven commands -main() ( - branch="${1?Missing branch name}"; shift - target_branch="${1?Missing target branch name}"; shift - pull_request_id="${1?Missing pull request id}"; shift - extraBuildParams=("$@") - - declare -a LIST_FILE_ARRAY=( $(find $(pwd) -type f -name 'jacoco.xml') ) - LIST_FILE=$(IFS=, ; echo "${LIST_FILE_ARRAY[*]}") - - # Fetch target branch for Sonar diff purpose - git fetch origin "${target_branch}":"${target_branch}" - - # Why sonar plugin is not declared in pom.xml: https://blog.sonarsource.com/we-had-a-dream-mvn-sonarsonar - # TODO https://jira.talendforge.org/browse/TDI-48980 (CI: Reactivate Sonar cache) - mvn sonar:sonar \ - --define 'sonar.host.url=https://sonar-eks.datapwn.com' \ - --define "sonar.login=${SONAR_LOGIN}" \ - --define "sonar.password=${SONAR_PASSWORD}" \ - --define "sonar.coverage.jacoco.xmlReportPaths='${LIST_FILE}'" \ - --define "sonar.analysisCache.enabled=false" \ - --define "sonar.pullrequest.branch=${branch}" \ - --define "sonar.pullrequest.base=${target_branch}" \ - --define "sonar.pullrequest.key=${pull_request_id}" \ - "${extraBuildParams[@]}" - - -) - -main "$@" diff --git a/.jenkins/scripts/npm_fix.sh b/.jenkins/scripts/npm_fix.sh index ff66d6527b35a..6ee1918a3a35c 100755 --- a/.jenkins/scripts/npm_fix.sh +++ b/.jenkins/scripts/npm_fix.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash # -# Copyright (C) 2006-2024 Talend Inc. - www.talend.com +# Copyright (C) 2006-2025 Talend Inc. - www.talend.com # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/.jenkins/scripts/package.sh b/.jenkins/scripts/package.sh index 12503b031ae0e..edf8dd3e3152c 100644 --- a/.jenkins/scripts/package.sh +++ b/.jenkins/scripts/package.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash # -# Copyright (C) 2006-2024 Talend Inc. - www.talend.com +# Copyright (C) 2006-2025 Talend Inc. - www.talend.com # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/.jenkins/scripts/post-release.sh b/.jenkins/scripts/post-release.sh index 120650b0cfe40..044c7113c32b2 100755 --- a/.jenkins/scripts/post-release.sh +++ b/.jenkins/scripts/post-release.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash # -# Copyright (C) 2006-2024 Talend Inc. - www.talend.com +# Copyright (C) 2006-2025 Talend Inc. - www.talend.com # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/.jenkins/scripts/release/release-2-prepare.sh b/.jenkins/scripts/release/release-2-prepare.sh new file mode 100644 index 0000000000000..7a99b1210a35e --- /dev/null +++ b/.jenkins/scripts/release/release-2-prepare.sh @@ -0,0 +1,47 @@ +#!/usr/bin/env bash +# +# Copyright (C) 2006-2025 Talend Inc. - www.talend.com +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +set -xe + +# Parameters: +# $1: release version +# $2: next version +# $3: tag name +# $4: extra build args for all mvn cmd +main() { + local releaseVersion="${1?Missing release version}"; shift + local nextVersion="${1?Missing actual project version}"; shift + local tagName="${1?Missing actual project version}"; shift + local extraBuildParams=("$@") + + printf ">> Maven prepare release %s (next-dev: %s; tag: %s)\n" "${releaseVersion}" "${nextVersion}" "${tagName}" + + local release_profiles="release,ossrh,gpg2" + + mvn release:prepare \ + --batch-mode \ + --errors \ + --define tag="${tagName}" \ + --define releaseVersion="${releaseVersion}" \ + --define developmentVersion="${nextVersion}" \ + --define arguments="-DskipTests -DskipITs -Dcheckstyle.skip -Denforcer.skip=true -Drat.skip" \ + --settings .jenkins/settings.xml \ + --activate-profiles "$release_profiles" \ + "${extraBuildParams[@]}" +} + +main "$@" diff --git a/.jenkins/scripts/release/release-3-perform.sh b/.jenkins/scripts/release/release-3-perform.sh new file mode 100644 index 0000000000000..89240ad9529ac --- /dev/null +++ b/.jenkins/scripts/release/release-3-perform.sh @@ -0,0 +1,39 @@ +#!/usr/bin/env bash +# +# Copyright (C) 2006-2025 Talend Inc. - www.talend.com +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +set -xe + +# Parameters: +# $1: extra build args for all mvn cmd +main() { + local extraBuildParams=("$@") + + printf ">> Maven perform release" + + local release_profiles="release,ossrh,gpg2" + + mvn release:perform \ + --batch-mode \ + --errors \ + --define arguments="-DskipTests -DskipITs -Dcheckstyle.skip -Denforcer.skip=true -Drat.skip" \ + --settings .jenkins/settings.xml \ + --activate-profiles "$release_profiles" \ + "${extraBuildParams[@]}" + +} + +main "$@" diff --git a/.jenkins/scripts/release/release-3.1-perform-studio.sh b/.jenkins/scripts/release/release-3.1-perform-studio.sh new file mode 100644 index 0000000000000..99814e4190d91 --- /dev/null +++ b/.jenkins/scripts/release/release-3.1-perform-studio.sh @@ -0,0 +1,47 @@ +#!/usr/bin/env bash +# +# Copyright (C) 2006-2025 Talend Inc. - www.talend.com +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +set -xe + +# Parameters: +# $1: release version +# $2: next version +# $3: extra build args for all mvn cmd +main() { + local releaseVersion="${1?Missing release version}"; shift + local nextVersion="${1?Missing actual project version}"; shift + local extraBuildParams=("$@") + + printf ">> Maven perform release" + + # todo: add gpg2 profile for signing artifacts + local release_profiles="release-zl" + + # set the release version in the pom.xml + mvn versions:set -DnewVersion="${releaseVersion}" + + mvn clean deploy \ + --file "component-studio/pom.xml" \ + --define arguments="-DskipTests -DskipITs -Dcheckstyle.skip -Denforcer.skip=true -Drat.skip" \ + --settings .jenkins/settings.xml \ + --activate-profiles ${release_profiles} \ + "${extraBuildParams[@]}" + + mvn versions:set -DnewVersion="${nextVersion}" +} + +main "$@" diff --git a/.jenkins/scripts/release/release-4-docker-image-creation.sh b/.jenkins/scripts/release/release-4-docker-image-creation.sh new file mode 100644 index 0000000000000..3f7c8ec57b573 --- /dev/null +++ b/.jenkins/scripts/release/release-4-docker-image-creation.sh @@ -0,0 +1,47 @@ +#!/usr/bin/env bash +# +# Copyright (C) 2006-2025 Talend Inc. - www.talend.com +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +set -xe + +# Parameters: +# $1: release version +# $2: tag name +# $3: branch name +main() { + local releaseVersion="${1?Missing release version}" + local tagName="${2?Missing actual project version}" + local branchName="${3?Missing actual project version}" + + printf ">> Docker image creation from branch %s with tag: %s on version %s\n" "$releaseVersion" "$tagName" "$branchName" + printf "Reset repo\n" + git reset --hard + git push -u origin "${branchName}" --follow-tags + + printf "Checkout the release tag as a branch\n" + git checkout -b "${tagName}" "${tagName}" + + printf "Activate lastest tagging for master branch\n" + local tag_latest="" + if [[ ${branchName} == 'master' ]]; then + tag_latest="true" + fi + + printf "Docker build call\n" + bash .jenkins/scripts/docker_build.sh "${releaseVersion}" "${tag_latest}" +} + +main "$@" diff --git a/.jenkins/scripts/release/release-5-prepare-next-iteration.sh b/.jenkins/scripts/release/release-5-prepare-next-iteration.sh new file mode 100644 index 0000000000000..3f80e4ce2d10a --- /dev/null +++ b/.jenkins/scripts/release/release-5-prepare-next-iteration.sh @@ -0,0 +1,45 @@ +#!/usr/bin/env bash +# +# Copyright (C) 2006-2025 Talend Inc. - www.talend.com +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +set -xe + +# Parameters: +# $1: branch name +# $2: extra build args for all mvn cmd +main() { + local branchName="${1?Missing actual project version}"; shift + local extraBuildParams=("$@") + + printf ">> Rebuilding %s and updating it (doc) for next iteration\n" "${branchName}" + git reset --hard + git checkout "${branchName}" + + # "|| true" is here to avoid blocking the jenkins pipeline in case of failure + mvn clean install --define skipTests \ + --define invoker.skip=true \ + --define checkstyle.skip \ + --define enforcer.skip=true \ + --define rat.skip \ + "${extraBuildParams[@]}" || true + + printf "Push to github\n" + git commit -a -m "Updating doc for next iteration" || true + git push -u origin "${branchName}" || true + +} + +main "$@" diff --git a/.jenkins/scripts/release/release-6-create-maintenance-branch.sh b/.jenkins/scripts/release/release-6-create-maintenance-branch.sh new file mode 100644 index 0000000000000..21e3bc42d28ce --- /dev/null +++ b/.jenkins/scripts/release/release-6-create-maintenance-branch.sh @@ -0,0 +1,44 @@ +#!/usr/bin/env bash +# +# Copyright (C) 2006-2025 Talend Inc. - www.talend.com +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +set -xe + +# Parameters: +# $1: maintenance branch name +# $2: maintenance version +main() { + local maintenanceBranch="${1?Missing maintenance branch name}" + local maintenanceVersion="${2?Missing maintenance version}" + + printf ">> Creating %s with %s\n" "${maintenanceBranch}" "${maintenanceVersion}" + + git checkout -b "${maintenanceBranch}" + + printf "Downgrade project to maintenance version\n" + mvn versions:set \ + --batch-mode \ + --settings .jenkins/settings.xml \ + --define generateBackupPoms=false \ + --define newVersion="${maintenanceVersion}" + + printf "Push maintenance branch\n" + git commit -a -m "[jenkins-release] prepare for next development iteration ${maintenanceBranch}" + git push -u origin "${maintenanceBranch}" + +} + +main "$@" diff --git a/.jenkins/scripts/release.sh b/.jenkins/scripts/release_legacy.sh old mode 100755 new mode 100644 similarity index 85% rename from .jenkins/scripts/release.sh rename to .jenkins/scripts/release_legacy.sh index 95c1aae56ec4d..9c98fa9244341 --- a/.jenkins/scripts/release.sh +++ b/.jenkins/scripts/release_legacy.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash # -# Copyright (C) 2006-2024 Talend Inc. - www.talend.com +# Copyright (C) 2006-2025 Talend Inc. - www.talend.com # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -46,11 +46,6 @@ main() { fi local dev_version=${maj}.${min}.${rev}-SNAPSHOT ### - echo ">> Preparing and installing BOM to release ${release} from ${currentVersion}" - mvn versions:set --define newVersion="${release}" --define generateBackupPoms=false -f bom/pom.xml - mvn install -f bom/pom.xml - mvn versions:set --define newVersion="${currentVersion}" --define generateBackupPoms=false -f bom/pom.xml - ### echo ">> Maven prepare release $release (next-dev: ${dev_version}; maintenance: ${maintenance_branch} with ${maintenance_version})" mvn release:prepare \ --batch-mode \ @@ -94,13 +89,6 @@ main() { echo ">> Creating ${maintenance_branch?Missing branch} with ${maintenance_version?Missing version}" git checkout -b "${maintenance_branch}" # downgrade to maintenance version - mvn versions:set \ - --batch-mode \ - --settings .jenkins/settings.xml \ - --define generateBackupPoms=false \ - --define newVersion="${maintenance_version}" \ - -f bom/pom.xml - mvn versions:set \ --batch-mode \ --settings .jenkins/settings.xml \ diff --git a/.jenkins/scripts/setup_gpg.sh b/.jenkins/scripts/setup_gpg.sh index f940c51e8efad..60152e59d4651 100644 --- a/.jenkins/scripts/setup_gpg.sh +++ b/.jenkins/scripts/setup_gpg.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash # -# Copyright (C) 2006-2024 Talend Inc. - www.talend.com +# Copyright (C) 2006-2025 Talend Inc. - www.talend.com # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/.jenkins/scripts/trivy_build_tck.sh b/.jenkins/scripts/trivy_build_tck.sh new file mode 100644 index 0000000000000..a0c635a348e36 --- /dev/null +++ b/.jenkins/scripts/trivy_build_tck.sh @@ -0,0 +1,42 @@ +#!/usr/bin/env bash +# +# Copyright (C) 2006-2025 Talend Inc. - www.talend.com +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +set -xe + +main() { + echo "Building project with Maven skipping most of the checks" + + mvn clean install --projects '!talend-component-maven-plugin' \ + --projects '!documentation' \ + --settings .jenkins/settings.xml \ + --batch-mode \ + --update-snapshots \ + --show-version \ + --define skipTests \ + --define gpg.skip=true \ + --define enforcer.skip=true\ + --define spotless.apply.skip=true \ + --define spotbugs.skip=true \ + --define checkstyle.skip=true \ + --define rat.skip=true \ + --define maven.test.skip=true \ + --define maven.javadoc.skip=true \ + --define invoker.skip=true \ + --define maven.artifact.threads=25 +} + +main "$@" diff --git a/.jenkins/scripts/asdf_install.sh b/.jenkins/scripts/trivy_scan.sh similarity index 66% rename from .jenkins/scripts/asdf_install.sh rename to .jenkins/scripts/trivy_scan.sh index 0994b5c4a867e..df173af781bdb 100644 --- a/.jenkins/scripts/asdf_install.sh +++ b/.jenkins/scripts/trivy_scan.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash # -# Copyright (C) 2006-2024 Talend Inc. - www.talend.com +# Copyright (C) 2006-2025 Talend Inc. - www.talend.com # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -18,9 +18,16 @@ set -xe main() { - asdf install - asdf reshim - asdf current + echo "Printing Trivy version:" + trivy --version + + echo "Running Trivy scan:" + mkdir -p output + trivy fs . -f json \ + --scanners vuln \ + -o output/trivy-results.json \ + --timeout 60m \ + --debug } main "$@" diff --git a/.jenkins/scripts/trivy_upload.sh b/.jenkins/scripts/trivy_upload.sh new file mode 100644 index 0000000000000..867acbdcecae9 --- /dev/null +++ b/.jenkins/scripts/trivy_upload.sh @@ -0,0 +1,41 @@ +#!/usr/bin/env bash +# +# Copyright (C) 2006-2025 Talend Inc. - www.talend.com +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +set -xe + +main() { + echo "Scan completed, now uploading to DefectDojo" + + curl -s -X 'POST' -H "Authorization: Token ${DEFECTDOJO_API_TOKEN}" \ + 'https://defectdojo.dagali.talendinc.com/api/v2/reimport-scan/' \ + -H 'accept: application/json' \ + -H 'Content-Type: multipart/form-data' \ + -F 'close_old_findings=true' \ + -F 'engagement_name=trivy-sca_component-runtime' \ + -F 'auto_create_context=true' \ + -F 'push_to_jira=false' \ + -F 'scan_date=' \ + -F 'do_not_reactivate=true' \ + -F 'minimum_severity=Low' \ + -F 'product_name=component-runtime' \ + -F 'verified=true' \ + -F 'product_type_name=Talend' \ + -F 'scan_type=Trivy Scan' \ + -F 'file=@output/trivy-results.json' +} + +main "$@" diff --git a/.jenkins/scripts/veracode-sca.sh b/.jenkins/scripts/veracode-sca.sh index b0fdbaf9b316b..4f67146de0cf8 100644 --- a/.jenkins/scripts/veracode-sca.sh +++ b/.jenkins/scripts/veracode-sca.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash # -# Copyright (C) 2006-2024 Talend Inc. - www.talend.com +# Copyright (C) 2006-2025 Talend Inc. - www.talend.com # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/.jenkins/settings.xml b/.jenkins/settings.xml index 7ecc9ea5105b6..b1144552d2cfc 100644 --- a/.jenkins/settings.xml +++ b/.jenkins/settings.xml @@ -5,14 +5,14 @@ https://maven.apache.org/xsd/settings-1.0.0.xsd"> - ossrh + central.portal ${env.OSSRH_USER} ${env.OSSRH_PASS} github - ${env.GITHUB_USER} - ${env.GITHUB_PASS} + ${env.GITHUB_LOGIN} + ${env.GITHUB_TOKEN} jira diff --git a/.tool-versions b/.tool-versions index 0595fcebba2a3..3836c1c1548e2 100644 --- a/.tool-versions +++ b/.tool-versions @@ -1,2 +1,3 @@ java adoptopenjdk-17.0.5+8 -maven 3.8.5 +maven 3.9.9 +trivy 0.54.1 diff --git a/Jenkinsfile b/Jenkinsfile index 12c1bb31fcb6a..6921acc42c4b4 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -1,5 +1,5 @@ /** - * Copyright (C) 2006-2024 Talend Inc. - www.talend.com + * Copyright (C) 2006-2025 Talend Inc. - www.talend.com * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,40 +19,42 @@ import java.util.regex.Matcher // Credentials final def ossrhCredentials = usernamePassword( - credentialsId: 'ossrh-credentials', - usernameVariable: 'OSSRH_USER', - passwordVariable: 'OSSRH_PASS') + credentialsId: 'ossrh-credentials', + usernameVariable: 'OSSRH_USER', + passwordVariable: 'OSSRH_PASS') final def nexusCredentials = usernamePassword( - credentialsId: 'nexus-artifact-zl-credentials', - usernameVariable: 'NEXUS_USER', passwordVariable: 'NEXUS_PASS') + credentialsId: 'nexus-artifact-zl-credentials', + usernameVariable: 'NEXUS_USER', passwordVariable: 'NEXUS_PASS') final def jetbrainsCredentials = usernamePassword( - credentialsId: 'jetbrains-credentials', - usernameVariable: 'JETBRAINS_USER', - passwordVariable: 'JETBRAINS_PASS') + credentialsId: 'jetbrains-credentials', + usernameVariable: 'JETBRAINS_USER', + passwordVariable: 'JETBRAINS_PASS') final def jiraCredentials = usernamePassword( - credentialsId: 'jira-credentials', - usernameVariable: 'JIRA_USER', - passwordVariable: 'JIRA_PASS') + credentialsId: 'jira-credentials', + usernameVariable: 'JIRA_USER', + passwordVariable: 'JIRA_PASS') final def gitCredentials = usernamePassword( - credentialsId: 'github-credentials', - usernameVariable: 'GITHUB_USER', - passwordVariable: 'GITHUB_PASS') + credentialsId: 'github-credentials', + usernameVariable: 'GITHUB_LOGIN', + passwordVariable: 'GITHUB_TOKEN') final def dockerCredentials = usernamePassword( - credentialsId: 'artifactory-datapwn-credentials', - usernameVariable: 'DOCKER_USER', - passwordVariable: 'DOCKER_PASS') + credentialsId: 'artifactory-datapwn-credentials', + usernameVariable: 'DOCKER_USER', + passwordVariable: 'DOCKER_PASS') final def sonarCredentials = usernamePassword( - credentialsId: 'sonar-credentials', - usernameVariable: 'SONAR_LOGIN', - passwordVariable: 'SONAR_PASSWORD') + credentialsId: 'sonar-credentials', + usernameVariable: 'SONAR_LOGIN', + passwordVariable: 'SONAR_PASSWORD') final def keyImportCredentials = usernamePassword( - credentialsId: 'component-runtime-import-key-credentials', - usernameVariable: 'KEY_USER', - passwordVariable: 'KEY_PASS') + credentialsId: 'component-runtime-import-key-credentials', + usernameVariable: 'KEY_USER', + passwordVariable: 'KEY_PASS') final def gpgCredentials = usernamePassword( - credentialsId: 'component-runtime-gpg-credentials', - usernameVariable: 'GPG_KEYNAME', - passwordVariable: 'GPG_PASSPHRASE') + credentialsId: 'component-runtime-gpg-credentials', + usernameVariable: 'GPG_KEYNAME', + passwordVariable: 'GPG_PASSPHRASE') + +final String repository = 'component-runtime' // In PR environment, the branch name is not valid and should be swap with pr name. final String pull_request_id = env.CHANGE_ID @@ -61,9 +63,10 @@ final String branch_name = pull_request_id != null ? env.CHANGE_BRANCH : env.BRA // Job config final Boolean isMasterBranch = branch_name == "master" final Boolean isStdBranch = (branch_name == "master" || branch_name.startsWith("maintenance/")) -final Boolean hasPostLoginScript = params.POST_LOGIN_SCRIPT != "" final String extraBuildParams = "" final String buildTimestamp = String.format('-%tY% dev branches are deploying on ''') - booleanParam( - name: 'DOCKER_PUSH', - defaultValue: false, - description: ''' + booleanParam( + name: 'DOCKER_PUSH', + defaultValue: false, + description: ''' Force DOCKER push stage for development branches. No effect on master and maintenance. INFO: master/maintenance and dev branches are deploying on ''') - string( - name: 'VERSION_QUALIFIER', - defaultValue: 'DEFAULT', - description: ''' + choice( + name: 'DOCKER_CHOICE', + choices: ['component-server', + 'component-starter-server', + 'remote-engine-customizer', + 'All'], + description: 'Choose which docker image you want to build and push. Only available if DOCKER_PUSH == True.') + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////// + separator(name: "QUALIFIER_CONFIG", + sectionHeader: "Qualifier configuration", + sectionHeaderStyle: """ background-color: #AED6F1; + text-align: center; font-size: 35px !important; font-weight : bold; + """) + /////////////////////////////////////////////////////////////////////////////////////////////////////////////// + string( + name: 'VERSION_QUALIFIER', + defaultValue: 'DEFAULT', + description: ''' Deploy jars with the given version qualifier. No effect on master and maintenance. - DEFAULT means the qualifier will be the Jira id extracted from the branch name. From "user/JIRA-12345_some_information" the qualifier will be JIRA-12345.''') - string( - name: 'EXTRA_BUILD_PARAMS', - defaultValue: '', - description: 'Add some extra parameters to maven commands. Applies to all maven calls.') - string( - name: 'POST_LOGIN_SCRIPT', - defaultValue: '', - description: 'Execute a shell command after login. Useful for maintenance.') - booleanParam( - name: 'DISABLE_SONAR', - defaultValue: false, - description: 'Cancel the Sonar analysis stage execution') - booleanParam( - name: 'FORCE_DOC', - defaultValue: false, - description: 'Force documentation stage for development branches. No effect on master and maintenance.') - booleanParam( - name: 'FORCE_SECURITY_ANALYSIS', - defaultValue: false, - description: 'Force OSS security analysis stage for branches.') - booleanParam( - name: 'FORCE_DEPS_REPORT', - defaultValue: false, - description: 'Force dependencies report stage for branches.') - booleanParam( - name: 'JENKINS_DEBUG', - defaultValue: false, - description: 'Add an extra step to the pipeline allowing to keep the pod alive for debug purposes.') - } - stages { - stage('Preliminary steps') { - steps { - - /////////////////////////////////////////// - // Login tasks - /////////////////////////////////////////// - script { - withCredentials([gitCredentials]) { - sh """ bash .jenkins/scripts/git_login.sh "\${GITHUB_USER}" "\${GITHUB_PASS}" """ - } - withCredentials([dockerCredentials]) { - sh """ bash .jenkins/scripts/docker_login.sh "${ARTIFACTORY_REGISTRY}" "\${DOCKER_USER}" "\${DOCKER_PASS}" """ - } - withCredentials([keyImportCredentials]) { - sh """ bash .jenkins/scripts/setup_gpg.sh """ - } - } - /////////////////////////////////////////// - // asdf install - /////////////////////////////////////////// - script { - println "asdf install the content of repository .tool-versions'\n" - sh 'bash .jenkins/scripts/asdf_install.sh' - } - /////////////////////////////////////////// - // Variables init - /////////////////////////////////////////// - script { - stdBranch_buildOnly = isStdBranch && params.Action != 'RELEASE' - devBranch_mavenDeploy = !isStdBranch && params.MAVEN_DEPLOY - devBranch_dockerPush = !isStdBranch && params.DOCKER_PUSH - - needQualify = devBranch_mavenDeploy || devBranch_dockerPush - - if (needQualify) { - // Qualified version have to be released on talend_repository - // Overwrite the deployOptions - deployOptions = "$skipOptions --activate-profiles private_repository -Denforcer.skip=true" - } - - // By default the doc is skipped for standards branches - Boolean skip_documentation = !( params.FORCE_DOC || isStdBranch ) - extraBuildParams = assemblyExtraBuildParams(skip_documentation) - - } - /////////////////////////////////////////// - // Pom version and Qualifier management - /////////////////////////////////////////// - script{ - final def pom = readMavenPom file: 'pom.xml' - pomVersion = pom.version - - echo 'Manage the version qualifier' - if (!needQualify) { - println """ - No need to add qualifier in followings cases: - - We are on Master or Maintenance branch - - We do not want to deploy on dev branch - """.stripIndent() - finalVersion = pomVersion - } - else { - branch_user = "" - branch_ticket = "" - branch_description = "" - if (params.VERSION_QUALIFIER != ("DEFAULT")) { - // If the qualifier is given, use it - println """No need to add qualifier, use the given one: "$params.VERSION_QUALIFIER" """ - } - else { - println "Validate the branch name" - - (branch_user, - branch_ticket, - branch_description) = extract_branch_info(branch_name) - - // Check only branch_user, because if there is an error all three params are empty. - if (branch_user == ("")) { - println """ - ERROR: The branch name doesn't comply with the format: user/JIRA-1234-Description - It is MANDATORY for artifact management. - You have few options: - - You do not need to deploy, uncheck MAVEN_DEPLOY checkbox - - Change the VERSION_QUALIFIER text box to a personal qualifier, BUT you need to do it on ALL se/ee and cloud-components build - - Rename your branch - """.stripIndent() - currentBuild.description = ("ERROR: The branch name is not correct") - sh """exit 1""" - } - } - - echo "Insert a qualifier in pom version..." - finalVersion = add_qualifier_to_version( - pomVersion, - branch_ticket, - "$params.VERSION_QUALIFIER" as String) - - echo """ - Configure the version qualifier for the curent branche: $branch_name - requested qualifier: $params.VERSION_QUALIFIER - with User = $branch_user, Ticket = $branch_ticket, Description = $branch_description - Qualified Version = $finalVersion""" - - // On development branches the connectors version shall be edited for deployment - // Maven documentation about maven_version: - // https://docs.oracle.com/middleware/1212/core/MAVEN/maven_version.htm - println "Edit version on dev branches, new version is ${finalVersion}" - sh """\ - #!/usr/bin/env bash - mvn versions:set --define newVersion=${finalVersion} - mvn versions:set --file bom/pom.xml --define newVersion=${finalVersion} - """.stripIndent() - } - - } - /////////////////////////////////////////// - // Updating build displayName and description - /////////////////////////////////////////// - script { - String user_name = currentBuild.getBuildCauses('hudson.model.Cause$UserIdCause').userId[0] - if ( user_name == null) { user_name = "auto" } - - String deploy_info = '' - if (stdBranch_buildOnly || devBranch_mavenDeploy){ - deploy_info = deploy_info + '+DEPLOY' - } - if (devBranch_dockerPush){ - deploy_info = deploy_info + '+DOCKER' - } - - currentBuild.displayName = ( - "#$currentBuild.number-$params.Action" + deploy_info + ": $user_name" - ) - - // updating build description - String description = """ - Version = $finalVersion - $params.Action Build - Disable Sonar: $params.DISABLE_SONAR - Script: $hasPostLoginScript - Debug: $params.JENKINS_DEBUG - Extra build args: $extraBuildParams""".stripIndent() - job_description_append(description) - } - } - post { - always { - println "Artifact Poms files for analysis if needed" - archiveArtifacts artifacts: '**/*pom.*', allowEmptyArchive: false, onlyIfSuccessful: false - } - } + /////////////////////////////////////////////////////////////////////////////////////////////////////////////// + separator(name: "ADVANCED_CONFIG", + sectionHeader: "Advanced configuration", + sectionHeaderStyle: """ background-color: #F8C471; + text-align: center; font-size: 35px !important; font-weight : bold; + """) + /////////////////////////////////////////////////////////////////////////////////////////////////////////////// + string( + name: 'EXTRA_BUILD_PARAMS', + defaultValue: '', + description: 'Add some extra parameters to maven commands. Applies to all maven calls.') + booleanParam( + name: 'DISABLE_SONAR', + defaultValue: false, + description: 'Cancel the Sonar analysis stage execution') + booleanParam( + name: 'FORCE_SECURITY_ANALYSIS', + defaultValue: false, + description: 'Force OSS security analysis stage for branches.') + booleanParam( + name: 'FORCE_DEPS_REPORT', + defaultValue: false, + description: 'Force dependencies report stage for branches.') + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////// + separator(name: "EXPERT_CONFIG", + sectionHeader: "Expert configuration", + sectionHeaderStyle: """ background-color: #A9A9A9; + text-align: center; font-size: 35px !important; font-weight : bold; + """) + /////////////////////////////////////////////////////////////////////////////////////////////////////////////// + booleanParam( + name: 'TRIVY_SCAN', + defaultValue: !isStdBranch, + description: ''' + This is for trivy scan, by default this checkbox is false on master or maintenance branch. + It will generate the trivy report on Jenkins, the report name is `CVE Trivy Vulnerability Report` + ''') + string( + name: 'PACKAGE_FILTER_NAME', + defaultValue: "", + description: ''' + This input box is used to filter the results of the `mvn dependency:tree` command. + This input box only works when TRIVY_SCAN checkbox is true. + By entering the package name, you can find out which components are affected and thus the scope of the test. + For example: org.eclipse.jetty:jetty-http, org.apache.avro:avro, org.apache.geronimo ...''') + /////////////////////////////////////////////////////////////////////////////////////////////////////////////// + separator(name: "DEBUG_CONFIG", + sectionHeader: "Jenkins job debug configuration ", + sectionHeaderStyle: """ background-color: #FF0000; + text-align: center; font-size: 35px !important; font-weight : bold; + """) + /////////////////////////////////////////////////////////////////////////////////////////////////////////////// + booleanParam( + name: 'JENKINS_DEBUG', + defaultValue: false, + description: 'Add an extra step to the pipeline allowing to keep the pod alive for debug purposes.') + } + + stages { + stage('Preliminary steps') { + steps { + + /////////////////////////////////////////// + // Login tasks + /////////////////////////////////////////// + script { + withCredentials([gitCredentials]) { + GitController.gitLogin() + } + withCredentials([dockerCredentials]) { + sh """ bash .jenkins/scripts/docker_login.sh "${ARTIFACTORY_REGISTRY}" "\${DOCKER_USER}" "\${DOCKER_PASS}" """ + } + withCredentials([keyImportCredentials]) { + sh """ bash .jenkins/scripts/setup_gpg.sh """ + } } - stage('Post login') { - steps { - withCredentials([gitCredentials, - dockerCredentials, - ossrhCredentials, - jetbrainsCredentials, - jiraCredentials, - gpgCredentials]) { - script { - try { - sh """\ - #!/usr/bin/env bash - bash "${params.POST_LOGIN_SCRIPT}" - bash .jenkins/scripts/npm_fix.sh - """.stripIndent() - } catch (ignored) { - // - } - } - } - } + + /////////////////////////////////////////// + // edit mvn and java version + /////////////////////////////////////////// + script { + String javaVersion = JenkinsPodConfig.asdfSetVersion("$env.WORKSPACE/.tool-versions", 'java', params.JAVA_VERSION) + String mavenVersion = JenkinsPodConfig.asdfSetVersion("$env.WORKSPACE/.tool-versions", 'maven', params.MAVEN_VERSION) + JenkinsStatusController.jobDescriptionAppend("Use java $javaVersion with maven $mavenVersion ") + JenkinsPodConfig.asdfInstall() } - stage('Maven validate to install') { - when { expression { params.Action != 'RELEASE' } } - steps { - withCredentials([ossrhCredentials, - nexusCredentials]) { - sh """\ - #!/usr/bin/env bash - set -xe - mvn clean install --file bom/pom.xml - mvn clean install $BUILD_ARGS \ - $extraBuildParams \ - --settings .jenkins/settings.xml - """.stripIndent() - } - } - post { - always { - recordIssues( - enabledForFailure: false, - tools: [ - junitParser( - id: 'unit-test', - name: 'Unit Test', - pattern: '**/target/surefire-reports/*.xml' - ) - ] - ) - } - } + + /////////////////////////////////////////// + // Variables init + /////////////////////////////////////////// + script { + stdBranch_buildOnly = isStdBranch && params.ACTION != 'RELEASE' + devBranch_mavenDeploy = !isStdBranch && params.MAVEN_DEPLOY + devBranch_dockerPush = !isStdBranch && params.DOCKER_PUSH + + needQualify = devBranch_mavenDeploy || devBranch_dockerPush + + if (needQualify) { + // Qualified version have to be released on talend_repository + // Overwrite the deployOptions + deployOptions = "$skipOptions --activate-profiles private_repository -Denforcer.skip=true" + } + + // hack to overwrite the skip of studio modules that we can't deploy in release mode into Sonatype repo + // assume that we don't use this Jenkinsfile for release anymore + deployOptions = deployOptions.replace("-Prelease", "-Psnapshot") + + // By default the doc is skipped for standards branches + Boolean skip_documentation = !(params.FORCE_DOC || isStdBranch) + extraBuildParams = assemblyExtraBuildParams(skip_documentation) + } - stage('Maven deploy') { - when { - anyOf { - expression { stdBranch_buildOnly } - expression { devBranch_mavenDeploy } - } + /////////////////////////////////////////// + // Pom version and Qualifier management + /////////////////////////////////////////// + script { + final def pom = readMavenPom file: 'pom.xml' + pomVersion = pom.version + + echo 'Manage the version qualifier' + if (!needQualify) { + println """ + No need to add qualifier in followings cases: + - We are on Master or Maintenance branch + - We do not want to deploy on dev branch + """.stripIndent() + finalVersion = pomVersion + } else { + branch_user = "" + branch_ticket = "" + branch_description = "" + if (params.VERSION_QUALIFIER != ("DEFAULT")) { + // If the qualifier is given, use it + println """No need to add qualifier, use the given one: "$params.VERSION_QUALIFIER" """ + } else { + println "Validate the branch name" + + (branch_user, + branch_ticket, + branch_description) = extract_branch_info(branch_name) + + // Check only branch_user, because if there is an error all three params are empty. + if (branch_user == ("")) { + println """ + ERROR: The branch name doesn't comply with the format: user/JIRA-1234-Description + It is MANDATORY for artifact management. + You have few options: + - You do not need to deploy, uncheck MAVEN_DEPLOY checkbox + - Change the VERSION_QUALIFIER text box to a personal qualifier, BUT you need to do it on ALL se/ee and cloud-components build + - Rename your branch + """.stripIndent() + currentBuild.description = ("ERROR: The branch name is not correct") + sh """exit 1""" + } } - steps { - script { - withCredentials([ossrhCredentials, - gpgCredentials, - nexusCredentials]) { - sh """\ + + echo "Insert a qualifier in pom version..." + finalVersion = add_qualifier_to_version( + pomVersion, + branch_ticket, + "$params.VERSION_QUALIFIER" as String) + + echo """ + Configure the version qualifier for the curent branche: $branch_name + requested qualifier: $params.VERSION_QUALIFIER + with User = $branch_user, Ticket = $branch_ticket, Description = $branch_description + Qualified Version = $finalVersion """ + + // On development branches the connectors version shall be edited for deployment + // Maven documentation about maven_version: + // https://docs.oracle.com/middleware/1212/core/MAVEN/maven_version.htm + println "Edit version on dev branches, new version is ${finalVersion}" + sh """\ #!/usr/bin/env bash - set -xe - bash mvn deploy $deployOptions \ - $extraBuildParams \ - --settings .jenkins/settings.xml + mvn versions:set --define newVersion=${finalVersion} """.stripIndent() - } - } - // Add description to job - script { - def repo - if (devBranch_mavenDeploy) { - repo = ['artifacts-zl.talend.com', - 'https://artifacts-zl.talend.com/nexus/content/repositories/snapshots/org/talend/sdk/component'] - } else { - repo = ['oss.sonatype.org', - 'https://oss.sonatype.org/content/repositories/snapshots/org/talend/sdk/component/'] - } - - job_description_append("Maven artefact deployed as ${finalVersion} on [${repo[0]}](${repo[1]})") - } - } + } + + } + /////////////////////////////////////////// + // Updating build displayName and description + /////////////////////////////////////////// + script { + String deploy_info = '' + if (stdBranch_buildOnly || devBranch_mavenDeploy) { + deploy_info = deploy_info + '+DEPLOY' + } + if (devBranch_dockerPush) { + deploy_info = deploy_info + '+DOCKER' + } + + JenkinsStatusController.jobNameCreation("$params.ACTION" + deploy_info) + + // updating build description + String description = """ + Version = $finalVersion - $params.ACTION Build + Disable Sonar: $params.DISABLE_SONAR + Debug: $params.JENKINS_DEBUG + Extra build args: $extraBuildParams """.stripIndent() + JenkinsStatusController.jobDescriptionAppend(description) + } + } + post { + always { + println "Artifact Poms files for analysis if needed" + archiveArtifacts artifacts: '**/*pom.*', allowEmptyArchive: false, onlyIfSuccessful: false + } + } + } + stage('Post login') { + steps { + withCredentials([gitCredentials, + dockerCredentials, + ossrhCredentials, + jetbrainsCredentials, + jiraCredentials, + gpgCredentials]) { + script { + sh """\ + #!/usr/bin/env bash + bash .jenkins/scripts/npm_fix.sh + """.stripIndent() + + // If needed, use jenkins replay function then uncomment this to add your temporary bash command + // This replace the POST_LOGIN_SCRIPT variable used prior to https://qlik-dev.atlassian.net/browse/QTDI-740 + // sh """\ + // #!/usr/bin/env bash + // bash but anything needed here + // """.stripIndent() + } + } + } + } + stage('Maven validate to install') { + when { expression { params.ACTION != 'RELEASE' } } + steps { + withCredentials([ossrhCredentials, + nexusCredentials]) { + sh """\ + #!/usr/bin/env bash + set -xe + mvn clean install $BUILD_ARGS \ + $extraBuildParams \ + --settings .jenkins/settings.xml + """.stripIndent() + } + } + post { + always { + recordIssues( + enabledForFailure: false, + tools: [ + junitParser( + id: 'unit-test', + name: 'Unit Test', + pattern: '**/target/surefire-reports/*.xml' + ) + ] + ) + } + } + } + stage('Maven deploy') { + when { + anyOf { + expression { stdBranch_buildOnly } + expression { devBranch_mavenDeploy } + } + } + steps { + script { + withCredentials([ossrhCredentials, + gpgCredentials, + nexusCredentials]) { + sh """\ + #!/usr/bin/env bash + set -xe + bash mvn deploy $deployOptions \ + $extraBuildParams \ + --settings .jenkins/settings.xml + """.stripIndent() + } + } + // Add description to job + script { + def repo + if (devBranch_mavenDeploy) { + repo = ['artifacts-zl.talend.com', + 'https://artifacts-zl.talend.com/nexus/content/repositories/snapshots/org/talend/sdk/component'] + } else { + repo = ['oss.sonatype.org', + 'https://central.sonatype.com/repository/maven-snapshots/org/talend/sdk/component/'] + } + + JenkinsStatusController.jobDescriptionAppend("Maven artefact deployed as ${finalVersion} on [${repo[0]}](${repo[1]}) ") } - stage('Docker build/push') { - when { - anyOf { - expression { stdBranch_buildOnly } - expression { devBranch_dockerPush } - } + } + } + stage('Docker build/push') { + when { + anyOf { + expression { stdBranch_buildOnly } + expression { devBranch_dockerPush } + } + } + steps { + script { + configFileProvider([configFile(fileId: 'maven-settings-nexus-zl', variable: 'MAVEN_SETTINGS')]) { + + String images_options = '' + if (isStdBranch) { + // Build and push all images + JenkinsStatusController.jobDescriptionAppend("Docker images deployed: component-server, component-starter-server and remote-engine-customizer ") + } else { + String image_list + if (params.DOCKER_CHOICE == 'All') { + images_options = 'false' + } else { + images_options = 'false ' + params.DOCKER_CHOICE + } + + if (params.DOCKER_CHOICE == 'All') { + JenkinsStatusController.jobDescriptionAppend("All docker images deployed ") + + JenkinsStatusController.jobDescriptionAppend("As ${finalVersion}${buildTimestamp} on " + + "[artifactory.datapwn.com]" + + "($artifactoryAddr/$artifactoryPath) ") + JenkinsStatusController.jobDescriptionAppend("docker pull $artifactoryAddr/$artifactoryPath" + + "/component-server:${finalVersion}${buildTimestamp} ") + JenkinsStatusController.jobDescriptionAppend("docker pull $artifactoryAddr/$artifactoryPath" + + "/component-starter-server:${finalVersion}${buildTimestamp} ") + JenkinsStatusController.jobDescriptionAppend("docker pull $artifactoryAddr/$artifactoryPath" + + "/remote-engine-customize:${finalVersion}${buildTimestamp} ") + + } else { + JenkinsStatusController.jobDescriptionAppend("Docker images deployed: $params.DOCKER_CHOICE ") + JenkinsStatusController.jobDescriptionAppend("As ${finalVersion}${buildTimestamp} on " + + "[artifactory.datapwn.com]($artifactoryAddr/$artifactoryPath) ") + JenkinsStatusController.jobDescriptionAppend("docker pull $artifactoryAddr/$artifactoryPath/$params.DOCKER_CHOICE:" + + "${finalVersion}${buildTimestamp} ") + + } + } - steps { - script { - configFileProvider([configFile(fileId: 'maven-settings-nexus-zl', variable: 'MAVEN_SETTINGS')]) { - - String images_options = '' - if (isStdBranch){ - // Build and push all images - job_description_append("Docker images deployed: component-server, component-starter-server and remote-engine-customizer") - } - else{ - images_options = 'false component-server' - job_description_append("Docker images deployed: component-server") - job_description_append("As ${finalVersion}${buildTimestamp} on [artifactory.datapwn.com](https://artifactory.datapwn.com/tlnd-docker-dev/talend/common/tacokit)" as String) - - } - - // Build and push specific image - sh """ - bash .jenkins/scripts/docker_build.sh \ - ${finalVersion}${buildTimestamp} \ - ${images_options} - """ - job_description_append("docker pull artifactory.datapwn.com/tlnd-docker-dev/talend/common/tacokit/component-server:${finalVersion}${buildTimestamp}") - } + // Build and push specific image + sh """ + bash .jenkins/scripts/docker_build.sh \ + ${finalVersion}${buildTimestamp} \ + ${images_options} + """ + } - } - } } - stage('Documentation') { - when { - expression { - params.FORCE_DOC || (params.Action != 'RELEASE' && isMasterBranch) - } - } - steps { - withCredentials([ossrhCredentials, gitCredentials]) { - sh """\ - #!/usr/bin/env bash - set -xe - mvn verify pre-site --file documentation/pom.xml \ - --settings .jenkins/settings.xml \ - --activate-profiles gh-pages \ - --define gpg.skip=true \ - $skipOptions \ - $extraBuildParams - """.stripIndent() - } - } + } + } + stage('Documentation') { + when { + expression { + params.FORCE_DOC || (params.ACTION != 'RELEASE' && isMasterBranch) } - stage('OSS security analysis') { - when { - anyOf { - expression { params.Action != 'RELEASE' && branch_name == 'master' } - expression { params.FORCE_SECURITY_ANALYSIS == true } - } - } - steps { - withCredentials([ossrhCredentials]) { - catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') { - sh """ - bash .jenkins/scripts/mvn-ossindex-audit.sh - """ - } - } - } - post { - always { - publishHTML( - target: [ - allowMissing : true, - alwaysLinkToLastBuild: false, - keepAll : true, - reportDir : 'target/', - reportFiles : 'audit.txt', - reportName : "security::audit" - ]) - } - } + } + steps { + withCredentials([ossrhCredentials, gitCredentials]) { + sh """\ + #!/usr/bin/env bash + set -xe + mvn verify pre-site --file documentation/pom.xml \ + --settings .jenkins/settings.xml \ + --activate-profiles gh-pages \ + --define gpg.skip=true \ + $skipOptions \ + $extraBuildParams + """.stripIndent() } - stage('Deps report') { - when { - anyOf { - expression { params.Action != 'RELEASE' && branch_name == 'master' } - expression { params.FORCE_DEPS_REPORT == true } - } - } - steps { - withCredentials([ossrhCredentials]) { - catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') { - sh """ + } + } + stage('OSS security analysis') { + when { + anyOf { + expression { params.ACTION != 'RELEASE' && branch_name == 'master' } + expression { params.FORCE_SECURITY_ANALYSIS == true } + } + } + steps { + withCredentials([ossrhCredentials]) { + catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') { + sh """ + bash .jenkins/scripts/mvn-ossindex-audit.sh + """ + } + } + } + post { + always { + publishHTML( + target: [ + allowMissing : true, + alwaysLinkToLastBuild: false, + keepAll : true, + reportDir : 'target/', + reportFiles : 'audit.txt', + reportName : "security::audit" + ]) + } + } + } + stage('Deps report') { + when { + anyOf { + expression { params.ACTION != 'RELEASE' && branch_name == 'master' } + expression { params.FORCE_DEPS_REPORT == true } + } + } + steps { + withCredentials([ossrhCredentials, + nexusCredentials]) { + catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') { + sh """ bash .jenkins/scripts/mvn_dependency_updates_report.sh """ - } - } - } - post { - always { - publishHTML( - target: [ - allowMissing : true, - alwaysLinkToLastBuild: false, - keepAll : true, - reportDir : 'target/site/', - reportFiles : 'dependency-updates-report.html', - reportName : "outdated::dependency" - ]) - publishHTML( - target: [ - allowMissing : true, - alwaysLinkToLastBuild: false, - keepAll : true, - reportDir : 'target/site/', - reportFiles : 'plugin-updates-report.html', - reportName : "outdated::plugins" - ]) - } - } + } } - stage('Sonar') { - when { - expression { (params.Action != 'RELEASE') && !params.DISABLE_SONAR} - } - steps { - script { - withCredentials([nexusCredentials, - sonarCredentials, - gitCredentials]) { - - if (pull_request_id != null) { - - println 'Run analysis for PR' - sh """ - bash .jenkins/scripts/mvn_sonar_pr.sh \ - '${branch_name}' \ - '${env.CHANGE_TARGET}' \ - '${pull_request_id}' \ - ${extraBuildParams} - """ - } else { - echo 'Run analysis for branch' - sh """ - bash .jenkins/scripts/mvn_sonar_branch.sh \ - '${branch_name}' \ - ${extraBuildParams} - """ - } - } - } - } + } + post { + always { + publishHTML( + target: [ + allowMissing : true, + alwaysLinkToLastBuild: false, + keepAll : true, + reportDir : 'target/site/', + reportFiles : 'dependency-updates-report.html', + reportName : "outdated::dependency" + ]) + publishHTML( + target: [ + allowMissing : true, + alwaysLinkToLastBuild: false, + keepAll : true, + reportDir : 'target/site/', + reportFiles : 'plugin-updates-report.html', + reportName : "outdated::plugins" + ]) } - stage('Release') { - when { - allOf { - expression { params.Action == 'RELEASE' } - expression { isStdBranch } - } - } - steps { - script { - withCredentials([gitCredentials, dockerCredentials, ossrhCredentials, jetbrainsCredentials, jiraCredentials, gpgCredentials, nexusCredentials]) { - configFileProvider([configFile(fileId: 'maven-settings-nexus-zl', variable: 'MAVEN_SETTINGS')]) { - sh """ - bash .jenkins/scripts/release.sh $branch_name $finalVersion $extraBuildParams + } + } + stage('Sonar') { + when { + expression { (params.ACTION != 'RELEASE') && !params.DISABLE_SONAR } + } + steps { + script { + withCredentials([nexusCredentials, + sonarCredentials, + gitCredentials]) { + + SonarController.runSonar(branch_name, + env.CHANGE_TARGET, + pull_request_id, + extraBuildParams, + 'jacoco.xml', // jacocoGlob + false) // useCache false https://qlik-dev.atlassian.net/browse/QTDI-234 + } + } + } + } + stage('Release') { + when { + allOf { + expression { params.ACTION == 'RELEASE' } + expression { isStdBranch } + } + } + steps { + script { + withCredentials([gitCredentials, dockerCredentials, ossrhCredentials, jetbrainsCredentials, jiraCredentials, gpgCredentials, nexusCredentials]) { + configFileProvider([configFile(fileId: 'maven-settings-nexus-zl', variable: 'MAVEN_SETTINGS')]) { + sh """ + bash .jenkins/scripts/release_legacy.sh $branch_name $finalVersion $extraBuildParams """ - } - } - } } + } } + } } - post { - success { - script { - //Only post results to Slack for Master and Maintenance branches - if (isStdBranch) { - slackSend( - color: '#00FF00', - message: "SUCCESSFUL: Job '${env.JOB_NAME} [${env.BUILD_NUMBER}]' (${env.BUILD_URL})", - channel: "${env.SLACK_CI_CHANNEL}" - ) - } - } - script { - println "====== Publish Coverage" - publishCoverage adapters: [jacocoAdapter('**/jacoco-aggregate/*.xml')] - publishCoverage adapters: [jacocoAdapter('**/jacoco-it/*.xml')] - publishCoverage adapters: [jacocoAdapter('**/jacoco-ut/*.xml')] - println "====== Publish HTML API Coverage" - publishHTML([ - allowMissing : false, - alwaysLinkToLastBuild: false, - keepAll : true, - reportDir : 'reporting/target/site/jacoco-aggregate', - reportFiles : 'index.html', - reportName : 'Coverage', - reportTitles : 'Coverage' - ]) - } + stage('Trivy scan') { + when { + expression { params.ACTION == 'STANDARD' && params.TRIVY_SCAN == true } + } + steps { + script { + trivyTools.generateTrivyReport('output/trivy-results.json', + 'output/trivy-results.html') + publishHtmlReportTools.publishHtmlReport('output/trivy-results.html', + 'CVE Trivy Vulnerability Report') } - failure { - script { - //Only post results to Slack for Master and Maintenance branches - if (isStdBranch) { - //if previous build was a success, ping channel in the Slack message - if ("SUCCESS" == currentBuild.previousBuild.result) { - slackSend( - color: '#FF0000', - message: "@here : NEW FAILURE: Job '${env.JOB_NAME} [${env.BUILD_NUMBER}]' (${env.BUILD_URL})", - channel: "${env.SLACK_CI_CHANNEL}" - ) - } else { - //else send notification without pinging channel - slackSend( - color: '#FF0000', - message: "FAILED: Job '${env.JOB_NAME} [${env.BUILD_NUMBER}]' (${env.BUILD_URL})", - channel: "${env.SLACK_CI_CHANNEL}" - ) - } - } - } + } + post { + always { + catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') { + archiveArtifacts artifacts: "output/trivy-results.*", allowEmptyArchive: true, onlyIfSuccessful: false + } + } + } + } + stage('Mvn dependency:tree') { + when { + expression { params.ACTION == 'STANDARD' && params.TRIVY_SCAN == true } + } + steps { + script { + mvnDependencyTreeTools.generateScopeOfImpactReport("output/${repository}.txt", params.PACKAGE_FILTER_NAME, "output/${repository}--ScopeOfImpact.txt", repository) + publishHtmlReportTools.publishHtmlReport("output/${repository}.html", 'CVE mvn dependency:tree Report') + publishHtmlReportTools.publishHtmlReport("output/${repository}--ScopeOfImpact.html", 'CVE Scope Of Impact Report') } + } + post { always { - recordIssues( - enabledForFailure: false, - tools: [ - taskScanner( - id: 'disabled', - name: '@Disabled', - includePattern: '**/src/**/*.java', - ignoreCase: true, - normalTags: '@Disabled' - ), - taskScanner( - id: 'todo', - name: 'Todo(low)/Fixme(high)', - includePattern: '**/src/**/*.java', - ignoreCase: true, - highTags: 'FIX_ME, FIXME', - lowTags: 'TO_DO, TODO' - ) - ] - ) - script { - println '====== Archive jacoco reports artifacts' - archiveArtifacts artifacts: "${'**/jacoco-aggregate/**/*.*'}", allowEmptyArchive: true, onlyIfSuccessful: false - } - - script { - if (params.JENKINS_DEBUG) { - jenkinsBreakpoint() - } - } + catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') { + archiveArtifacts artifacts: "output/${repository}.txt, output/${repository}--ScopeOfImpact.txt", allowEmptyArchive: true, onlyIfSuccessful: false + } } + } } -} - + } + post { + success { + script { + println "====== Publish Coverage" + publishCoverage adapters: [jacocoAdapter('**/jacoco-aggregate/*.xml')] + publishCoverage adapters: [jacocoAdapter('**/jacoco-it/*.xml')] + publishCoverage adapters: [jacocoAdapter('**/jacoco-ut/*.xml')] + println "====== Publish HTML API Coverage" + publishHTML([ + allowMissing : false, + alwaysLinkToLastBuild: false, + keepAll : true, + reportDir : 'reporting/target/site/jacoco-aggregate', + reportFiles : 'index.html', + reportName : 'Coverage', + reportTitles : 'Coverage' + ]) + } + } + always { + script { + String prevResult = null + if (currentBuild.previousBuild) { + prevResult = currentBuild.previousBuild.result + } -/** - * Append a new line to job description - * This is MARKDOWN, do not forget double space at the end of line - * - * @param new line - * @return void - */ -private void job_description_append(String new_line) { - if (currentBuild.description == null) { - println "Create the job description with: \n$new_line" - currentBuild.description = new_line - } else { - println "Edit the job description adding: $new_line" - currentBuild.description = currentBuild.description + '\n' + new_line + alertingTools.slack_result( + env.SLACK_CI_CHANNEL, + currentBuild.result, + prevResult, + true, // Post for success + true, // Post for failure + "Failure of $pomVersion $params.ACTION.") + } + recordIssues( + enabledForFailure: false, + tools: [ + taskScanner( + id: 'disabled', + name: '@Disabled', + includePattern: '**/src/**/*.java', + ignoreCase: true, + normalTags: '@Disabled' + ), + taskScanner( + id: 'todo', + name: 'Todo(low)/Fixme(high)', + includePattern: '**/src/**/*.java', + ignoreCase: true, + highTags: 'FIX_ME, FIXME', + lowTags: 'TO_DO, TODO' + ) + ] + ) + script { + println '====== Archive jacoco reports artifacts' + archiveArtifacts artifacts: "${'**/jacoco-aggregate/**/*.*'}", allowEmptyArchive: true, onlyIfSuccessful: false + } + + script { + if (params.JENKINS_DEBUG) { + JenkinsController.jenkinsBreakpoint() + } + } } + } } /** @@ -692,47 +786,27 @@ private void job_description_append(String new_line) { * @return extraBuildParams as a string ready for mvn cmd */ private String assemblyExtraBuildParams(Boolean skip_doc) { - String extraBuildParams + String extraBuildParams - println 'Processing extraBuildParams' - final List buildParamsAsArray = [] + println 'Processing extraBuildParams' + final List buildParamsAsArray = [] - println 'Manage user params' - if ( params.EXTRA_BUILD_PARAMS ) { - buildParamsAsArray.add(params.EXTRA_BUILD_PARAMS as String) - } + println 'Manage user params' + if (params.EXTRA_BUILD_PARAMS) { + buildParamsAsArray.add(params.EXTRA_BUILD_PARAMS as String) + } - println 'Manage the skip_doc option' - if (skip_doc) { - buildParamsAsArray.add('--projects !documentation') - buildParamsAsArray.add('--define documentation.skip=true') - } + println 'Manage the skip_doc option' + if (skip_doc) { + buildParamsAsArray.add('--projects !documentation') + buildParamsAsArray.add('--define documentation.skip=true') + } - println 'Construct final params content' - extraBuildParams = buildParamsAsArray.join(' ') - println "extraBuildParams: $extraBuildParams" + println 'Construct final params content' + extraBuildParams = buildParamsAsArray.join(' ') + println "extraBuildParams: $extraBuildParams" - return extraBuildParams -} - -/** - * Implement a simple breakpoint to stop actual job - * Use the method anywhere you need to stop - * The first usage is to keep the pod alive on post stage. - * Change and restore the job description to be more visible - * - * @param none - * @return void - */ -private void jenkinsBreakpoint() { - // Backup the description - String job_description_backup = currentBuild.description - // updating build description - currentBuild.description = "ACTION NEEDED TO CONTINUE \n ${job_description_backup}" - // Request user action - input message: 'Finish the job?', ok: 'Yes' - // updating build description - currentBuild.description = "$job_description_backup" + return extraBuildParams } /** @@ -749,18 +823,18 @@ private void jenkinsBreakpoint() { * @return String new_version with added qualifier */ private static String add_qualifier_to_version(String version, String ticket, String user_qualifier) { - String new_version + String new_version - if (user_qualifier.contains("DEFAULT")) { - if (version.contains("-SNAPSHOT")) { - new_version = version.replace("-SNAPSHOT", "-$ticket-SNAPSHOT" as String) - } else { - new_version = "$version-$ticket".toString() - } + if (user_qualifier.contains("DEFAULT")) { + if (version.contains("-SNAPSHOT")) { + new_version = version.replace("-SNAPSHOT", "-$ticket-SNAPSHOT" as String) } else { - new_version = version.replace("-SNAPSHOT", "-$user_qualifier-SNAPSHOT" as String) + new_version = "$version-$ticket".toString() } - return new_version + } else { + new_version = version.replace("-SNAPSHOT", "-$user_qualifier-SNAPSHOT" as String) + } + return new_version } /** @@ -776,19 +850,19 @@ private static String add_qualifier_to_version(String version, String ticket, St */ private static ArrayList extract_branch_info(String branch_name) { - String branchRegex = /^(?.*)\/(?[A-Z]{2,8}-\d{1,6})[_-](?.*)/ - Matcher branchMatcher = branch_name =~ branchRegex + String branchRegex = /^(?.*)\/(?[A-Z]{2,8}-\d{1,6})[_-](?.*)/ + Matcher branchMatcher = branch_name =~ branchRegex - try { - assert branchMatcher.matches() - } - catch (AssertionError ignored) { - return ["", "", ""] - } + try { + assert branchMatcher.matches() + } + catch (AssertionError ignored) { + return ["", "", ""] + } - String user = branchMatcher.group("user") - String ticket = branchMatcher.group("ticket") - String description = branchMatcher.group("description") + String user = branchMatcher.group("user") + String ticket = branchMatcher.group("ticket") + String description = branchMatcher.group("description") - return [user, ticket, description] -} + return [user, ticket, description] +} \ No newline at end of file diff --git a/bom/pom.xml b/bom/pom.xml deleted file mode 100644 index c4c8f12e9e271..0000000000000 --- a/bom/pom.xml +++ /dev/null @@ -1,308 +0,0 @@ - - - - 4.0.0 - - org.talend.sdk.component - component-bom - 1.64.9-SNAPSHOT - pom - Component BOM - Talend Component Kit - https://talend.github.io/component-runtime/ - - - Apache License, Version 2.0 - https://github.com/talend/component-runtime/blob/master/LICENSE - may be downloaded from the Maven repository - - - - - undx - Emmanuel GALLOIS - egallois@talend.com - Talend - https://www.talend.com/ - - Owner - - +1 - - - clesaec - Christophe Le Saec - clesaec@talend.com - Talend - https://www.talend.com/ - - Contributor - - +1 - - - - scm:git:git://github.com/talend/component-runtime.git - scm:git:git@github.com:talend/component-runtime.git - component-runtime-1.64.8 - https://github.com/talend/component-runtime - - - - ossrh - https://oss.sonatype.org/service/local/staging/deploy/maven2/ - - - ossrh - https://oss.sonatype.org/content/repositories/snapshots - - - - - 3.6.0 - 3.0.0 - 3.0.1 - 1.6.12 - - 1.7.34 - 1.2.21 - 2.20.0 - - 1.15 - 1.24.0 - 3.11 - - 2.16.0 - 2.16.0 - - 1.70 - 2.13.0 - - - 1.82 - - - - - - org.apache.httpcomponents - httpclient - 4.5.14 - - - commons-io - commons-io - ${commons-io.version} - - - org.bouncycastle - bcprov-jdk15on - ${bouncycastle.version} - - - org.bouncycastle - bcpkix-jdk15on - ${bouncycastle.version} - - - org.bouncycastle - bcpg-jdk15on - ${bouncycastle.version} - - - com.fasterxml.jackson.core - jackson-annotations - ${jackson.version} - - - com.fasterxml.jackson.core - jackson-core - ${jackson.version} - - - com.fasterxml.jackson.core - jackson-databind - ${jackson-databind.version} - - - com.google.guava - guava - 32.1.3-jre - - - org.talend.sdk.component - component-api - ${project.version} - - - commons-codec - commons-codec - ${commons-codec.version} - - - org.apache.commons - commons-compress - ${commons-compress.version} - - - org.apache.commons - commons-lang3 - ${commons-lang3.version} - - - org.apache.johnzon - johnzon-jaxrs - ${johnzon.version} - - - org.apache.johnzon - johnzon-jsonb - ${johnzon.version} - - - org.apache.johnzon - johnzon-core - ${johnzon.version} - - - org.apache.logging.log4j - log4j-api - ${log4j2.version} - - - org.apache.logging.log4j - log4j-core - ${log4j2.version} - - - org.apache.logging.log4j - log4j-jul - ${log4j2.version} - - - org.slf4j - log4j-over-slf4j - ${slf4j.version} - - - org.slf4j - slf4j-api - ${slf4j.version} - - - org.slf4j - slf4j-simple - ${slf4j.version} - - - org.slf4j - slf4j-jdk14 - ${slf4j.version} - - - com.beust - jcommander - ${jcommander.version} - - - - - - - org.apache.maven.plugins - maven-enforcer-plugin - ${enforcer-plugin.version} - - - enforce-maven-3 - - enforce - - - - - ${mvn-minimal.version} - - - true - - - - - - - - - gpg2 - - - - org.apache.maven.plugins - maven-gpg-plugin - ${gpg-plugin.version} - - - - - - release - - - - org.sonatype.plugins - nexus-staging-maven-plugin - ${nexus-staging-plugin.version} - true - - ossrh - https://oss.sonatype.org/ - true - - - - org.apache.maven.plugins - maven-gpg-plugin - ${gpg-plugin.version} - - - sign-artifacts - - sign - - verify - - - - - - - - no-staging - - - - org.sonatype.plugins - nexus-staging-maven-plugin - ${nexus-staging-plugin.version} - - true - - - - - - - diff --git a/bom/readme.adoc b/bom/readme.adoc deleted file mode 100644 index e00bc5050e5d6..0000000000000 --- a/bom/readme.adoc +++ /dev/null @@ -1,2 +0,0 @@ -This folder https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html[contains BOM file] for connectors using this TCK component. - diff --git a/ci/Jenkinsfile-release b/ci/Jenkinsfile-release new file mode 100644 index 0000000000000..13547c7591a09 --- /dev/null +++ b/ci/Jenkinsfile-release @@ -0,0 +1,580 @@ +/** + * Copyright (C) 2006-2025 Talend Inc. - www.talend.com + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Credentials +final def ossrhCredentials = usernamePassword( + credentialsId: 'ossrh-credentials', + usernameVariable: 'OSSRH_USER', + passwordVariable: 'OSSRH_PASS') +final def nexusCredentials = usernamePassword( + credentialsId: 'nexus-artifact-zl-credentials', + usernameVariable: 'NEXUS_USER', + passwordVariable: 'NEXUS_PASS') +final def jetbrainsCredentials = usernamePassword( + credentialsId: 'jetbrains-credentials', + usernameVariable: 'JETBRAINS_USER', + passwordVariable: 'JETBRAINS_PASS') +final def jiraCredentials = usernamePassword( + credentialsId: 'jira-credentials', + usernameVariable: 'JIRA_USER', + passwordVariable: 'JIRA_PASS') +final def gitCredentials = usernamePassword( + credentialsId: 'github-credentials', + usernameVariable: 'GITHUB_LOGIN', + passwordVariable: 'GITHUB_TOKEN') +final def dockerCredentials = usernamePassword( + credentialsId: 'artifactory-datapwn-credentials', + usernameVariable: 'DOCKER_USER', + passwordVariable: 'DOCKER_PASS') +final def keyImportCredentials = usernamePassword( + credentialsId: 'component-runtime-import-key-credentials', + usernameVariable: 'KEY_USER', + passwordVariable: 'KEY_PASS') +final def gpgCredentials = usernamePassword( + credentialsId: 'component-runtime-gpg-credentials', + usernameVariable: 'GPG_KEYNAME', + passwordVariable: 'GPG_PASSPHRASE') + +// In some cases the branch name is not valid, we define it here +final String branchName = env.BRANCH_NAME + +// Job config +final Boolean isMasterBranch = branchName == 'master' +final Boolean isMaintenanceBranch = branchName.startsWith('maintenance/') +final Boolean isMaintenanceRelease = false +final String extraBuildParams = "" + +// Job variables declaration +String pomVersion // Declared version in the pom file +String releaseVersion // Released version for the release +String nextVersion // Final version after the release +String tagName // created git tag name +String maintenanceVersion // Final version after the release for created maintenance branch +String maintenanceBranch // created maintenance branch name + +pipeline { + libraries { + lib("connectors-lib@1.2.0") // https://github.com/Talend/tdi-jenkins-shared-libraries + lib("tqa-e2e-tests-tool@v2.4.2-ttp2") // https://github.com/Talend/tqa-e2e-testing-tool + } + + agent { + kubernetes { + yamlFile '.jenkins/jenkins_pod.yml' + defaultContainer 'main' + } + } + + environment { + MAVEN_OPTS = [ + "-Dmaven.artifact.threads=256", + "-Dformatter.skip=true", + ].join(' ') + } + + options { + buildDiscarder(logRotator(artifactNumToKeepStr: '5', numToKeepStr: '5')) + timeout(time: 180, unit: 'MINUTES') + skipStagesAfterUnstable() + } + + parameters { + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////// + separator(name: "BASIC_CONFIG", sectionHeader: "Basic configuration", + sectionHeaderStyle: """ background-color: #ABEBC6; + text-align: center; font-size: 35px !important; font-weight : bold;""") + /////////////////////////////////////////////////////////////////////////////////////////////////////////////// + choice( + name: 'ACTION', + choices: ['TYPE_OF_RELEASE', 'GA', 'MAINTENANCE'], + description: ''' + Type of release: + GA: release for General Available + ex: 1.63.0-SNAPSHOT is released as 1.63.0 and master branch is bumped as 1.64.0-SNAPSHOT + MAINTENANCE: release for General Available of MAINTENANCE + ex: 1.63.1-SNAPSHOT is released as 1.63.1 and branch is bumped as 1.63.2-SNAPSHOT''') + + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////// + separator(name: "VERSION_CONFIG", sectionHeader: "Version configuration", + sectionHeaderStyle: """ background-color: #F9E79F; + text-align: center; font-size: 35px !important; font-weight : bold; """) + /////////////////////////////////////////////////////////////////////////////////////////////////////////////// + string(name: 'JAVA_VERSION', + defaultValue: 'from .tool-versions', + description: """Provided java version will be installed with asdf + Examples: adoptopenjdk-11.0.22+7, adoptopenjdk-17.0.11+9 """) + + string(name: 'MAVEN_VERSION', + defaultValue: 'from .tool-versions', + description: """Provided maven version will be installed with asdf + Examples: 3.8.8, 4.0.0-beta-4 """) + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////// + separator(name: "ADVANCED_CONFIG", sectionHeader: "Advanced configuration", + sectionHeaderStyle: """ background-color: #F8C471; + text-align: center; font-size: 35px !important; font-weight : bold; """) + /////////////////////////////////////////////////////////////////////////////////////////////////////////////// + string( + name: 'EXTRA_BUILD_PARAMS', + defaultValue: '', + description: 'Add some extra parameters to maven commands. Applies to all maven calls.') + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////// + separator(name: "EXPERT_CONFIG", sectionHeader: "Expert configuration", + sectionHeaderStyle: """ background-color: #A9A9A9; + text-align: center; font-size: 35px !important; font-weight : bold; """) + /////////////////////////////////////////////////////////////////////////////////////////////////////////////// + booleanParam( + name: 'RELEASE_STUDIO_MODULES', + defaultValue: true, + description: '''Activate release of studio modules. + EXPERT USER ONLY: to solve specials case eg: release ok but it fails for the Studio modules. + ''') + booleanParam( + name: 'NO_STAGING', + defaultValue: false, + description: '''Activate the no-staging profile. + Execute the release, but at the end of the release:perform step, + the artifacts are not publish on the NEXUS. + EXPERT USER ONLY: to solve specials case eg: release ok but failure during docker publish. + ''') + booleanParam( + name: 'NO_DOCKER', + defaultValue: false, + description: '''Skip the docker stage. + EXPERT USER ONLY: to solve specials case eg: release script test. + ''') + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////// + separator(name: "DEBUG_CONFIG", sectionHeader: "Jenkins job debug configuration ", + sectionHeaderStyle: """ background-color: #FF0000; + text-align: center; font-size: 35px !important; font-weight : bold; """) + /////////////////////////////////////////////////////////////////////////////////////////////////////////////// + booleanParam( + name: 'FAKE_RELEASE', + defaultValue: false, + description: '''For debug purposes, the job will deploy in: + - NOT IMPLEMENTED Artifactory Dev instead of Artifactory Prod for docker images + - NOT IMPLEMENTED Artifacts-zl instead of sonatype for java artefacts + - The job will not tag/commit on git fork from FAKE_REPOSITORY''') + string( + name: 'FAKE_REPOSITORY', + defaultValue: 'acatoire/component-runtime', + description: '''For debug purposes, to indicate the FAKE_RELEASE git repository''') + + booleanParam( + name: 'JENKINS_DEBUG', + defaultValue: false, + description: 'Add an extra step to the pipeline allowing to keep the pod alive for debug purposes.') + } + + stages { + stage('Prepare') { + steps { + + /////////////////////////////////////////// + // Login tasks + /////////////////////////////////////////// + script { + withCredentials([gitCredentials]) { + GitController.gitLogin() + } + withCredentials([dockerCredentials]) { + // DOCKER_REGISTRY_HOST comes from global jenkins managed env var (in flux config) + sh """ bash .jenkins/scripts/docker_login.sh "${DOCKER_REGISTRY_HOST}" "\${DOCKER_USER}" "\${DOCKER_PASS}" """ + } + withCredentials([keyImportCredentials]) { + sh """ bash .jenkins/scripts/setup_gpg.sh """ + } + } + + /////////////////////////////////////////// + // asdf install + /////////////////////////////////////////// + script { + String javaVersion = JenkinsPodConfig.asdfSetVersion("$env.WORKSPACE/.tool-versions", 'java', params.JAVA_VERSION) + String mavenVersion = JenkinsPodConfig.asdfSetVersion("$env.WORKSPACE/.tool-versions", 'maven', params.MAVEN_VERSION) + JenkinsStatusController.jobDescriptionAppend("Use java $javaVersion with maven $mavenVersion ") + JenkinsPodConfig.asdfInstall() + } + + /////////////////////////////////////////// + // assemblyExtraBuildParams + /////////////////////////////////////////// + script { + println "Create assemblyExtraBuildParams from user provided parameters and job option" + extraBuildParams = assemblyExtraBuildParams(params.FAKE_RELEASE as Boolean, + params.NO_STAGING as Boolean) + } + + /////////////////////////////////////////// + // Updating build displayName and description + /////////////////////////////////////////// + script { + JenkinsStatusController.jobNameCreation("$params.ACTION") + + // updating build description + String description = """ + Execute a $params.ACTION release. + Debug: $params.JENKINS_DEBUG + Extra build args: $extraBuildParams + """.stripIndent() + JenkinsStatusController.jobDescriptionAppend(description) + + if (params.FAKE_RELEASE) { + // updating build description + description = """ + --------------------------------------------------- + This is a fake release: + - artefacts will be posted on artifact-zl + - docker image will be deployed on artifactory dev + --------------------------------------------------- + + """.stripIndent() + JenkinsStatusController.jobDescriptionAppend(description) + } + } + } + } + + stage('Post login') { + steps { + withCredentials([gitCredentials, + dockerCredentials, + ossrhCredentials, + jetbrainsCredentials, + jiraCredentials, + gpgCredentials]) { + script { + sh """\ + #!/usr/bin/env bash + bash .jenkins/scripts/npm_fix.sh + """.stripIndent() + } + } + } + } + + stage('Version management') { + steps { + /////////////////////////////////////////// + // ACTION check + /////////////////////////////////////////// + script { + // Check on maintenance branch + if (isMaintenanceBranch) { + if (params.ACTION == 'MAINTENANCE') { + echo("GA release on maintenance branch") + isMaintenanceRelease = true + } + else { + error("On maintenance branch, you can only execute a MAINTENANCE release action") + } + } + + // Check on maintenance branch + if (isMasterBranch) { + switch (action) { + case 'GA': + echo("GA release on master branch") + break + default: + error("On master branch, you can only execute a GA release action") + } + } + + if (!isMasterBranch && !isMaintenanceBranch) { + error("You can only execute a release action on master or maintenance branch") + } + } + + /////////////////////////////////////////// + // Pom version management + /////////////////////////////////////////// + script { + echo 'Read the actual version in the pom' + final def pom = readMavenPom file: 'pom.xml' + pomVersion = pom.version + + echo 'Manage the release version ' + (releaseVersion, nextVersion, + maintenanceVersion, maintenanceBranch) = get_release_info(pomVersion, + isMaintenanceRelease) + tagName = "component-runtime-${releaseVersion}" + } + } + } + + stage('Version validation') { + steps { + script { + + /////////////////////////////////////////// + // Updating build description and name with calculated info + /////////////////////////////////////////// + JenkinsStatusController.jobNameCreation("$releaseVersion") + + String description = """ + ---------------------------------------------------------------- + Actual Version $pomVersion will be release as $releaseVersion. + After the release the repository will be bumped as $nextVersion. + ---------------------------------------------------------------- + + """.stripIndent() + JenkinsStatusController.jobDescriptionAppend(description) + + /////////////////////////////////////////// + // Manual validation of release action + /////////////////////////////////////////// + + String checkMsg = """ + You will do a $params.ACTION release + Actual Version $pomVersion will be release as $releaseVersion. + After the release the repository will be bumped as $nextVersion. + **Are you OK to continue?**""".stripIndent() + + // Request user action + input message: "$checkMsg", ok: 'Yes' + } + } + } + + stage('Maven release prepare') { + steps { + withCredentials([nexusCredentials, + ossrhCredentials, + gpgCredentials]) { + script { + echo "Maven prepare release $releaseVersion (next-dev: $nextVersion; tag: $tagName)" + sh "bash .jenkins/scripts/release/release-2-prepare.sh $releaseVersion \ + $nextVersion \ + $tagName \ + $extraBuildParams" + } + } + } + post { + always { + println "Publish prepared pom.xml files as Jenkins artifact for analysis" + archiveArtifacts artifacts: '**/*pom.xml', allowEmptyArchive: false, onlyIfSuccessful: false + } + } + } + + stage('Maven release process') { + steps { + withCredentials([nexusCredentials, + ossrhCredentials, + jetbrainsCredentials, + jiraCredentials, + gpgCredentials]) { + + script { + echo "Perform release" + sh "bash .jenkins/scripts/release/release-3-perform.sh $extraBuildParams" + } + } + } + } + + stage('Release studio modules') { + when { + expression { params.RELEASE_STUDIO_MODULES } + } + steps { + withCredentials([nexusCredentials, + ossrhCredentials, + jiraCredentials, + gpgCredentials]) { + + script { + echo "Perform release" + sh "bash .jenkins/scripts/release/release-3.1-perform-studio.sh $releaseVersion \ + $nextVersion \ + $extraBuildParams" + } + } + } + } + + stage('Release Docker image') { + when { + expression { !params.NO_DOCKER } + } + steps { + withCredentials([gitCredentials, + nexusCredentials, + ossrhCredentials, + dockerCredentials]) { + script { + echo "Docker image creation from branch $branchName with tag: $tagName on version $releaseVersion" + sh "bash .jenkins/scripts/release/release-4-docker-image-creation.sh $releaseVersion $tagName $branchName" + } + } + } + } + + stage('Prepare next iteration') { + steps { + withCredentials([gitCredentials, + nexusCredentials, + ossrhCredentials]) { + script { + echo "Prepare next iteration on $branchName" + sh "bash .jenkins/scripts/release/release-5-prepare-next-iteration.sh $branchName $extraBuildParams" + } + } + } + } + + stage('Create maintenance branch') { + when { + expression { isMasterBranch && params.ACTION == "GA" } + } + steps { + withCredentials([gitCredentials, + nexusCredentials, + ossrhCredentials]) { + script { + echo "Creating a new branch named $maintenanceBranch with version $maintenanceVersion" + sh "bash .jenkins/scripts/release/release-6-create-maintenance-branch.sh $maintenanceBranch $maintenanceVersion" + } + } + } + } + } + post { + always { + script { + alertingTools.slack_result( + env.SLACK_CI_CHANNEL, + currentBuild.result, + currentBuild.previousBuild.result, + true, // Post for success and failure for release scripts + true, + "Failure of $pomVersion $params.ACTION release.") + } + script { + if (params.JENKINS_DEBUG) { + JenkinsController.jenkinsBreakpoint() + } + } + } + } +} + +/** + * Assembly all needed items to put inside extraBuildParams + * + * @param Boolean fakeRelease + * @param Boolean noStaging + * + * @return extraBuildParams as a string ready for mvn cmd + */ +private String assemblyExtraBuildParams(Boolean fakeRelease, Boolean noStaging) { + String extraBuildParams + + println 'Processing extraBuildParams' + final List buildParamsAsArray = [] + + if (params.EXTRA_BUILD_PARAMS) { + buildParamsAsArray.add(params.EXTRA_BUILD_PARAMS as String) + } + + // Manage fake release parameter + if (fakeRelease) { + // Overwrite the git repository, in order not to write in "talend/component-runtime" + buildParamsAsArray.add("--define scm.repository=$params.FAKE_REPOSITORY") + } + + // Manage no-staging parameter + if (noStaging) { + buildParamsAsArray.add("--activate-profiles no-staging") + } + + println 'Construct final params content' + extraBuildParams = buildParamsAsArray.join(' ') + + println "extraBuildParams: $extraBuildParams" + + return extraBuildParams +} + + +/** + * Retrieves release information based on the provided current version. + * + * @param currentVersion The current version string to evaluate (e.g., "1.65.0M1-SNAPSHOT"). + * @param maintenance Indicates whether it is a maintenance release (true) or a main branch release (false). + * @return An ArrayList containing release information: + * - Index 0: Release version. + * - Index 1: Next development version. + * - Index 2: Maintenance version (empty string for main branch releases). + * - Index 3: Maintenance branch name (empty string for main branch releases). + */ +private static ArrayList get_release_info(String currentVersion, + Boolean maintenance) { + + println("Evaluate release name from current version: $currentVersion") + if (maintenance) { + println("This is a Maintenance release") + } + else { + println("This is a GA release") + } + + // Split the version (ex: "1.65.0M1-SNAPSHOT") on '.' and '-' + def parts = currentVersion.split(/[\.-]/) + int maj = parts[0] as int + int min = parts[1] as int + int rev = parts[2] as int + + String releaseVersion + releaseVersion = "${maj}.${min}.${rev}" + + println("Release version : $releaseVersion") + + // New maintenance branch need to be created. + String maintenanceBranch = "maintenance/${maj}.${min}" + String maintenanceVersion = "${maj}.${min}.${rev + 1}-SNAPSHOT" + println("Maintenance version : $releaseVersion") + println("Maintenance branch name : $maintenanceBranch") + + + // Calculate variables according to branch + String nextVersion + if (!maintenance) { + // master release + min++ + rev = 0 + + // Calculate the next development version + nextVersion = "${maj}.${min}.${rev}-SNAPSHOT" + + } + else { + // Maintenance release + rev++ + // Calculate the next development version + nextVersion = "${maj}.${min}.${rev}-SNAPSHOT" + } + + println("Next version : $nextVersion") + + return [releaseVersion, nextVersion, maintenanceVersion, maintenanceBranch] +} diff --git a/ci/Jenkinsfile-scan b/ci/Jenkinsfile-scan deleted file mode 100644 index 9aea58e363e06..0000000000000 --- a/ci/Jenkinsfile-scan +++ /dev/null @@ -1,243 +0,0 @@ -/** - * Copyright (C) 2006-2024 Talend Inc. - www.talend.com - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -final def slackChannel = 'components-ci' -final def veracodeCredentials = usernamePassword( - credentialsId: 'veracode-api-credentials', - usernameVariable: 'VERACODE_ID', - passwordVariable: 'VERACODE_KEY') -final def nexusCredentials = usernamePassword( - credentialsId: 'nexus-artifact-zl-credentials', - usernameVariable: 'NEXUS_USER', - passwordVariable: 'NEXUS_PASS') - -String git_branch_name = "" - -pipeline { - agent { - kubernetes { - yamlFile '.jenkins/jenkins_pod.yml' - defaultContainer 'main' - } - } - - environment { - MAVEN_OPTS = '-Dmaven.artifact.threads=128 -Dorg.slf4j.simpleLogger.showThreadName=true -Dorg.slf4j.simpleLogger.showDateTime=true -Dorg.slf4j.simpleLogger.dateTimeFormat=HH:mm:ss' - // Maven package skipped elements - // Everything that is not needed for the veracode scan is excluded to reduce time - SKIP_OPTS = "-Dspotless.apply.skip=true\ - -Dcheckstyle.skip=true\ - -Drat.skip=true\ - -DskipTests\ - -Dinvoker.skip=true\ - -pl '!talend-component-kit-intellij-plugin'\ - -pl '!reporting'" - TALEND_REGISTRY = 'registry.datapwn.com' - VERACODE_APP_NAME = 'Components' - VERACODE_SANDBOX = 'component-runtime' - APP_ID = '579232' - } - - options { - buildDiscarder(logRotator(artifactNumToKeepStr: '5', numToKeepStr: '5')) - timeout(time: 180, unit: 'MINUTES') - skipStagesAfterUnstable() - } - - parameters { - booleanParam( - name: 'VERACODE_SCA', - defaultValue: true, - description: 'Veracode SCA (Source Clear Analysis)') - booleanParam( - name: 'VERACODE_SAST', - defaultValue: true, - description: 'Veracode SAST (Static testing)') - booleanParam( - name: 'JENKINS_DEBUG', - defaultValue: false, - description: ''' - Add an extra comportment to the job allowing analysis: - - keep the pod alive for debug purposes''') - } - - stages { - stage('Preliminary steps') { - steps { - /////////////////////////////////////////// - // Update build info - /////////////////////////////////////////// - script { - def scans = [] - if (params.VERACODE_SCA) { - scans.add('SCA') - } - if (params.VERACODE_SAST) { - scans.add('SAST') - } - job_name_creation(scans.join('+')) - - git_branch_name = "${env.GIT_BRANCH}".replace("origin/", "") - job_description_append("Scanned branch: ${git_branch_name}") - } - /////////////////////////////////////////// - // asdf install - /////////////////////////////////////////// - script { - println "asdf install the content of repository .tool-versions'\n" - sh "bash .jenkins/scripts/asdf_install.sh" - } - /////////////////////////////////////////// - // npm_fix TODO maybe not needed if not root - /////////////////////////////////////////// - script { - try { - sh "bash .jenkins/scripts/npm_fix.sh" - } catch (npm_error) { - println("error running npm_fix.sh: ${npm_error}") - } - } - } - } - stage("Veracode SCA (Source Clear Analysis)") { - when { - expression { params.VERACODE_SCA } - } - steps { - withCredentials([string(credentialsId: 'veracode-token', variable: 'SRCCLR_API_TOKEN'), - nexusCredentials]) { - sh "bash .jenkins/scripts/veracode-sca.sh $SRCCLR_API_TOKEN" - } - } - } - stage('Package the app for Static testing') { - when { - expression { params.VERACODE_SAST } - } - steps { - withCredentials([veracodeCredentials, nexusCredentials]) { - script { - // Execute a mvn package skipping not needed element - sh "bash .jenkins/scripts/package.sh ${SKIP_OPTS}" - } - } - } - } - stage('Veracode SAST (Static testing)') { - when { - expression { params.VERACODE_SAST } - } - steps { - withCredentials([veracodeCredentials, nexusCredentials]) { - script { - veracode applicationName: "$VERACODE_SANDBOX", - teams: "Components", - canFailJob: true, - createProfile: true, - criticality: "High", - debug: true, - copyRemoteFiles: true, - fileNamePattern: '', - useProxy: false, - replacementPattern: '', - scanExcludesPattern: '', - scanIncludesPattern: '', - scanName: "${git_branch_name}-${currentBuild.number}-${currentBuild.startTimeInMillis}", - uploadExcludesPattern: '**/.cache/**/*.jar,**/*dep*/**/*.jar,**/lib/**/*.jar,**/*repo*/**/*.jar,**/it/**/*.jar,**/sample*.jar', - uploadIncludesPattern: '**/*.jar', - waitForScan: true, - vid: "$VERACODE_ID", - vkey: "$VERACODE_KEY" - } - } - } - } - } - post { - always { - script { - if (params.JENKINS_DEBUG) { - jenkinsBreakpoint() - } - } - } - success { - slackSend( - color: '#00FF00', - message: "SUCCESSFUL: Job '${env.JOB_NAME} [${env.BUILD_NUMBER}]' (${env.BUILD_URL})", - channel: "${slackChannel}") - } - failure { - slackSend(color: '#FF0000', - message: "FAILED: Job '${env.JOB_NAME} [${env.BUILD_NUMBER}]' (${env.BUILD_URL})", - channel: "${slackChannel}") - } - } -} - -/** - * Append a new line to job description - * REM This is MARKDOWN, do not forget double space at the end of line - * - * @param new line - * @return void - */ -private void job_name_creation(String extra) { - String user_name = currentBuild.getBuildCauses('hudson.model.Cause$UserIdCause').userId[0] - if (user_name == null) { - user_name = "auto" - } - - currentBuild.displayName = ( - "#$currentBuild.number-$extra-$user_name" - ) -} - -/** - * Append a new line to job description - * REM This is MARKDOWN, do not forget double space at the end of line - * - * @param new line - * @return void - */ -private void job_description_append(String new_line) { - if (currentBuild.description == null) { - println "Create the job description with: \n$new_line" - currentBuild.description = new_line - } else { - println "Edit the job description adding: $new_line" - currentBuild.description = currentBuild.description + '\n' + new_line - } -} - -/** - * Implement a simple breakpoint to stop actual job - * Use the method anywhere you need to stop - * The first usage is to keep the pod alive on post stage. - * Change and restore the job description to be more visible - * - * @param job_description_to_backup - * @return void - */ -private void jenkinsBreakpoint() { - // Backup the description - String job_description_backup = currentBuild.description - // updating build description - currentBuild.description = "ACTION NEEDED TO CONTINUE \n ${job_description_backup}" - // Request user action - input message: 'Finish the job?', ok: 'Yes' - // updating build description - currentBuild.description = "$job_description_backup" -} \ No newline at end of file diff --git a/ci/Jenkinsfile-trivy b/ci/Jenkinsfile-trivy new file mode 100644 index 0000000000000..46ea3f8d7c547 --- /dev/null +++ b/ci/Jenkinsfile-trivy @@ -0,0 +1,157 @@ +/** + * Copyright (C) 2006-2025 Talend Inc. - www.talend.com + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Credentials +final def nexusCredentials = usernamePassword( + credentialsId: 'nexus-artifact-zl-credentials', + usernameVariable: 'NEXUS_USER', + passwordVariable: 'NEXUS_PASSWORD') + +final String repository = 'component-runtime' + +pipeline { + libraries { + lib("connectors-lib@1.2.0") // https://github.com/Talend/tdi-jenkins-shared-libraries + lib("tqa-e2e-tests-tool@v2.4.2-ttp2") // https://github.com/Talend/tqa-e2e-testing-tool + } + + agent { + kubernetes { + yamlFile '.jenkins/jenkins_pod.yml' + defaultContainer 'main' + } + } + + environment { + MAVEN_OPTS = [ + '-Dmaven.artifact.threads=128', + '-Dorg.slf4j.simpleLogger.showThreadName=true', + '-Dorg.slf4j.simpleLogger.showDateTime=true', + '-Dorg.slf4j.simpleLogger.dateTimeFormat=HH:mm:ss', + ].join(' ') + TALEND_REGISTRY = 'registry.datapwn.com' + } + + options { + buildDiscarder(logRotator(artifactNumToKeepStr: '10', numToKeepStr: '10')) + timeout(time: 60, unit: 'MINUTES') + skipStagesAfterUnstable() + } + + + parameters { + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////// + separator(name: "BASIC_CONFIG", + sectionHeader: "Basic configuration", + sectionHeaderStyle: """ background-color: #ABEBC6; + text-align: center; font-size: 35px !important; font-weight : bold; + """) + /////////////////////////////////////////////////////////////////////////////////////////////////////////////// + string( + name: 'PACKAGE_FILTER_NAME', + defaultValue: "", + description: ''' + This input box is used to filter the results of the `mvn dependency:tree` command. + By entering the package name, you can find out which components are affected and thus the scope of the test. + For example: org.eclipse.jetty:jetty-http, org.apache.avro:avro, org.apache.geronimo ...''') + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////// + separator(name: "DEBUG_CONFIG", + sectionHeader: "Jenkins job debug configuration ", + sectionHeaderStyle: """ background-color: #FF0000; + text-align: center; font-size: 35px !important; font-weight : bold; + """) + /////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + booleanParam( + name: 'JENKINS_DEBUG', + defaultValue: false, + description: 'Add an extra step to the pipeline allowing to keep the pod alive for debug purposes.') + } + + stages { + stage('Prepare') { + steps { + script { + JenkinsPodConfig.asdfInstall() + } + } + } + + stage('Build Project') { + steps { + withCredentials([nexusCredentials]) { + script { + sh 'bash .jenkins/scripts/trivy_build_tck.sh' + } + } + } + } + + stage('Security Scan with Trivy') { + steps { + script { + trivyTools.generateTrivyReport("output/trivy-results.json", + "output/trivy-results.html") + publishHtmlReportTools.publishHtmlReport("output/trivy-results.html", "CVE Trivy Vulnerability Report") + } + } + post { + always { + catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') { + archiveArtifacts artifacts: 'output/trivy-results.json, output/trivy-results.html', allowEmptyArchive: true, onlyIfSuccessful: false + } + } + } + } + + stage('Upload Scan Results to DefectDojo') { + steps { + withCredentials([string(credentialsId: 'defectdojo-token-common', variable: 'DEFECTDOJO_API_TOKEN')]) { + sh 'bash .jenkins/scripts/trivy_upload.sh' + } + } + } + + stage('Mvn dependency:tree') { + steps { + script { + mvnDependencyTreeTools.generateScopeOfImpactReport("output/${repository}.txt", params.PACKAGE_FILTER_NAME, "output/${repository}--ScopeOfImpact.txt", repository) + publishHtmlReportTools.publishHtmlReport("output/${repository}.html", 'CVE mvn dependency:tree Report') + publishHtmlReportTools.publishHtmlReport("output/${repository}--ScopeOfImpact.html", 'CVE Scope Of Impact Report') + } + } + post { + always { + catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') { + archiveArtifacts artifacts: "output/${repository}.txt, output/${repository}--ScopeOfImpact.txt", allowEmptyArchive: true, onlyIfSuccessful: false + } + } + } + } + + } + post { + always { + script { + if (params.JENKINS_DEBUG) { + JenkinsController.jenkinsBreakpoint() + } + } + } + } +} diff --git a/component-api/pom.xml b/component-api/pom.xml index a32339365cd4d..5cd9599eab4ed 100644 --- a/component-api/pom.xml +++ b/component-api/pom.xml @@ -50,6 +50,7 @@ org.apache.johnzon johnzon-jsonb + ${johnzon.version} test diff --git a/component-form/component-form-core/pom.xml b/component-form/component-form-core/pom.xml index 67f02ca389b25..980a6b51379a1 100644 --- a/component-form/component-form-core/pom.xml +++ b/component-form/component-form-core/pom.xml @@ -35,6 +35,7 @@ org.slf4j slf4j-api + ${slf4j.version} org.apache.geronimo.specs @@ -79,6 +80,7 @@ org.apache.johnzon johnzon-jsonb + ${johnzon.version} test diff --git a/component-form/component-form-model/pom.xml b/component-form/component-form-model/pom.xml index 0abaae97838cb..d9ea5ffbfd080 100644 --- a/component-form/component-form-model/pom.xml +++ b/component-form/component-form-model/pom.xml @@ -46,6 +46,7 @@ org.apache.johnzon johnzon-jsonb + ${johnzon.version} test diff --git a/component-form/component-uispec-mapper/pom.xml b/component-form/component-uispec-mapper/pom.xml index 96f6c5c95d786..7f115ed3116e3 100644 --- a/component-form/component-uispec-mapper/pom.xml +++ b/component-form/component-uispec-mapper/pom.xml @@ -35,6 +35,7 @@ org.slf4j slf4j-api + ${slf4j.version} org.apache.geronimo.specs @@ -55,6 +56,7 @@ org.apache.johnzon johnzon-jsonb + ${johnzon.version} test diff --git a/component-runtime-beam/pom.xml b/component-runtime-beam/pom.xml index f80e5898a9149..25a853c27bfad 100644 --- a/component-runtime-beam/pom.xml +++ b/component-runtime-beam/pom.xml @@ -131,6 +131,7 @@ org.slf4j slf4j-jdk14 + ${slf4j.version} test diff --git a/component-runtime-design-extension/pom.xml b/component-runtime-design-extension/pom.xml index 6d6aca887b4fa..9a16c540b01d1 100644 --- a/component-runtime-design-extension/pom.xml +++ b/component-runtime-design-extension/pom.xml @@ -41,6 +41,7 @@ org.slf4j slf4j-jdk14 + ${slf4j.version} provided diff --git a/component-runtime-impl/pom.xml b/component-runtime-impl/pom.xml index 00d9fb7133a2c..5b4ba30df4bba 100644 --- a/component-runtime-impl/pom.xml +++ b/component-runtime-impl/pom.xml @@ -41,11 +41,13 @@ org.slf4j slf4j-api + ${slf4j.version} provided org.apache.johnzon johnzon-jsonb + ${johnzon.version} org.apache.logging.log4j diff --git a/component-runtime-manager/pom.xml b/component-runtime-manager/pom.xml index 992dded476157..b2ced2766ad50 100644 --- a/component-runtime-manager/pom.xml +++ b/component-runtime-manager/pom.xml @@ -78,11 +78,13 @@ org.apache.johnzon johnzon-core + ${johnzon.version} org.slf4j slf4j-jdk14 + ${slf4j.version} provided diff --git a/component-runtime-testing/component-runtime-http-junit/pom.xml b/component-runtime-testing/component-runtime-http-junit/pom.xml index 87f81492206df..e9d1d140428dd 100644 --- a/component-runtime-testing/component-runtime-http-junit/pom.xml +++ b/component-runtime-testing/component-runtime-http-junit/pom.xml @@ -36,6 +36,7 @@ org.slf4j slf4j-api + ${slf4j.version} @@ -53,6 +54,7 @@ org.apache.johnzon johnzon-jsonb + ${johnzon.version} true diff --git a/component-runtime-testing/component-runtime-testing-spark/pom.xml b/component-runtime-testing/component-runtime-testing-spark/pom.xml index f351c12e09218..ecfa4bf1755b4 100644 --- a/component-runtime-testing/component-runtime-testing-spark/pom.xml +++ b/component-runtime-testing/component-runtime-testing-spark/pom.xml @@ -55,6 +55,7 @@ org.slf4j slf4j-api + ${slf4j.version} org.jboss.shrinkwrap.resolver @@ -129,6 +130,7 @@ org.slf4j log4j-over-slf4j + ${slf4j.version} test diff --git a/component-server-parent/component-server/pom.xml b/component-server-parent/component-server/pom.xml index 35a1dec0acc19..6ea2e69d8a51d 100644 --- a/component-server-parent/component-server/pom.xml +++ b/component-server-parent/component-server/pom.xml @@ -82,6 +82,7 @@ org.apache.johnzon johnzon-jsonb + ${johnzon.version} org.apache.commons diff --git a/component-server-parent/extensions/component-server-extension-api/pom.xml b/component-server-parent/extensions/component-server-extension-api/pom.xml index c41c6d70784a3..1b23be5a9b70d 100644 --- a/component-server-parent/extensions/component-server-extension-api/pom.xml +++ b/component-server-parent/extensions/component-server-extension-api/pom.xml @@ -65,6 +65,7 @@ org.slf4j slf4j-api + ${slf4j.version} diff --git a/component-starter-server/pom.xml b/component-starter-server/pom.xml index 0c0cc09ecea03..d7bd3a26b3d34 100644 --- a/component-starter-server/pom.xml +++ b/component-starter-server/pom.xml @@ -40,6 +40,7 @@ org.apache.johnzon johnzon-jsonb + ${johnzon.version} org.apache.meecrowave diff --git a/component-studio/component-runtime-di/pom.xml b/component-studio/component-runtime-di/pom.xml index 719aa9f3630ba..46db6c25fd343 100644 --- a/component-studio/component-runtime-di/pom.xml +++ b/component-studio/component-runtime-di/pom.xml @@ -101,6 +101,7 @@ org.slf4j slf4j-simple + ${slf4j.version} test diff --git a/component-tools/pom.xml b/component-tools/pom.xml index e863ecb4cc267..65678f8352c91 100644 --- a/component-tools/pom.xml +++ b/component-tools/pom.xml @@ -132,6 +132,7 @@ org.slf4j slf4j-jdk14 + ${slf4j.version} test diff --git a/container/container-core/pom.xml b/container/container-core/pom.xml index de46b7ccb0a9a..0a2708f537994 100644 --- a/container/container-core/pom.xml +++ b/container/container-core/pom.xml @@ -35,11 +35,13 @@ org.slf4j slf4j-api + ${slf4j.version} org.slf4j slf4j-jdk14 + ${slf4j.version} test diff --git a/documentation/pom.xml b/documentation/pom.xml index c62b0a5a703b0..4456bcb965095 100644 --- a/documentation/pom.xml +++ b/documentation/pom.xml @@ -169,6 +169,7 @@ org.apache.johnzon johnzon-jsonb + ${johnzon.version} provided diff --git a/pom.xml b/pom.xml index 1d9b8792bd831..42270ba91cc36 100644 --- a/pom.xml +++ b/pom.xml @@ -102,7 +102,6 @@ - bom component-api container component-spi @@ -279,6 +278,7 @@ 1.2.21 2.13.0 1.24.0 + 3.18.0 1.7.34 2.20.0 1.7.14 @@ -286,19 +286,11 @@ - - org.talend.sdk.component - component-bom - ${project.version} - pom - import - com.google.cloud.tools jib-core ${jib-core.version} - org.apache.geronimo.specs geronimo-annotation_1.3_spec @@ -405,6 +397,11 @@ commons-compress ${commons-compress.version} + + org.apache.commons + commons-lang3 + ${commons-lang3.version} + org.yaml snakeyaml @@ -1272,8 +1269,7 @@ - - + org.sonatype.ossindex.maven ossindex-maven-plugin 3.1.0 @@ -1332,9 +1328,9 @@ * limitations under the License. */]]> - + diff --git a/remote-engine-customizer/pom.xml b/remote-engine-customizer/pom.xml index eea7b37ca1452..0a0ce4ddffb1e 100644 --- a/remote-engine-customizer/pom.xml +++ b/remote-engine-customizer/pom.xml @@ -35,6 +35,7 @@ org.slf4j slf4j-api + ${slf4j.version} com.google.cloud.tools diff --git a/sample-parent/pom.xml b/sample-parent/pom.xml index 55e863d70003a..881fcb284ea3e 100644 --- a/sample-parent/pom.xml +++ b/sample-parent/pom.xml @@ -43,6 +43,7 @@ org.slf4j slf4j-jdk14 + ${slf4j.version} provided diff --git a/sample-parent/sample-connector/pom.xml b/sample-parent/sample-connector/pom.xml index f67892f3413a2..620185cd475d9 100644 --- a/sample-parent/sample-connector/pom.xml +++ b/sample-parent/sample-connector/pom.xml @@ -40,7 +40,6 @@ org.apache.commons commons-lang3 - 3.12.0 org.apache.commons diff --git a/singer-parent/singer-java/pom.xml b/singer-parent/singer-java/pom.xml index a9383489de8cb..137a7b72bd4d0 100644 --- a/singer-parent/singer-java/pom.xml +++ b/singer-parent/singer-java/pom.xml @@ -40,6 +40,7 @@ org.apache.johnzon johnzon-core + ${johnzon.version} diff --git a/slf4j-standard/pom.xml b/slf4j-standard/pom.xml index 358ca2824d1a1..19e46dada33ad 100644 --- a/slf4j-standard/pom.xml +++ b/slf4j-standard/pom.xml @@ -35,6 +35,7 @@ org.slf4j slf4j-api + ${slf4j.version} provided diff --git a/talend-component-maven-plugin/pom.xml b/talend-component-maven-plugin/pom.xml index 7448d1a2e1df8..e66897020f314 100644 --- a/talend-component-maven-plugin/pom.xml +++ b/talend-component-maven-plugin/pom.xml @@ -99,6 +99,7 @@ org.apache.johnzon johnzon-jsonb + ${johnzon.version} diff --git a/talend-component-maven-plugin/src/it/web/.jenkins/scripts/tcomp-build-fast.sh b/talend-component-maven-plugin/src/it/web/.jenkins/scripts/tcomp-build-fast.sh index 85f79775a0092..b4b522ddf74f9 100644 --- a/talend-component-maven-plugin/src/it/web/.jenkins/scripts/tcomp-build-fast.sh +++ b/talend-component-maven-plugin/src/it/web/.jenkins/scripts/tcomp-build-fast.sh @@ -55,7 +55,6 @@ main() ( --projects component-server-parent/component-server \ --projects talend-component-maven-plugin \ --projects sample-parent \ - --projects bom \ --also-make \ ${_MAVEN_TEST_SKIP} \ ${_MAVEN_FAST} diff --git a/vault-client/src/main/java/org/talend/sdk/components/vault/client/VaultClientSetup.java b/vault-client/src/main/java/org/talend/sdk/components/vault/client/VaultClientSetup.java index 04334eb69f568..18e9d70af0c5f 100644 --- a/vault-client/src/main/java/org/talend/sdk/components/vault/client/VaultClientSetup.java +++ b/vault-client/src/main/java/org/talend/sdk/components/vault/client/VaultClientSetup.java @@ -49,6 +49,7 @@ import javax.ws.rs.client.ClientBuilder; import javax.ws.rs.client.WebTarget; +import org.apache.cxf.transport.https.httpclient.DefaultHostnameVerifier; import org.eclipse.microprofile.config.inject.ConfigProperty; import org.talend.sdk.components.vault.configuration.Documentation; @@ -188,6 +189,7 @@ private ClientBuilder createClient(final ExecutorService executor, final Optiona final Optional keystoreType, final String keystorePassword, final Optional truststoreType, final List serverHostnames) { final ClientBuilder builder = ClientBuilder.newBuilder(); + final DefaultHostnameVerifier hostnameVerifier = new DefaultHostnameVerifier(); builder.connectTimeout(connectTimeout, MILLISECONDS); builder.readTimeout(readTimeout, MILLISECONDS); builder.executorService(executor); @@ -195,7 +197,7 @@ private ClientBuilder createClient(final ExecutorService executor, final Optiona builder.hostnameVerifier((host, session) -> true); builder.sslContext(createUnsafeSSLContext()); } else if (keystoreLocation.isPresent()) { - builder.hostnameVerifier((host, session) -> serverHostnames.contains(host)); + builder.hostnameVerifier(hostnameVerifier::verify); builder.sslContext(createSSLContext(keystoreLocation, keystoreType, keystorePassword, truststoreType)); } providers.map(it -> Stream.of(it.split(",")).map(String::trim).filter(v -> !v.isEmpty()).map(fqn -> {