Newer
Older
/*
* Copyright (C) 2023 Das Land Schleswig-Holstein vertreten durch den
* Ministerpräsidenten des Landes Schleswig-Holstein
* Staatskanzlei
* Abteilung Digitalisierung und zentrales IT-Management der Landesregierung
*
* Lizenziert unter der EUPL, Version 1.2 oder - sobald
* diese von der Europäischen Kommission genehmigt wurden -
* Folgeversionen der EUPL ("Lizenz");
* Sie dürfen dieses Werk ausschließlich gemäß
* dieser Lizenz nutzen.
* Eine Kopie der Lizenz finden Sie hier:
*
* https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
*
* Sofern nicht durch anwendbare Rechtsvorschriften
* gefordert oder in schriftlicher Form vereinbart, wird
* die unter der Lizenz verbreitete Software "so wie sie
* ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN -
* ausdrücklich oder stillschweigend - verbreitet.
* Die sprachspezifischen Genehmigungen und Beschränkungen
* unter der Lizenz sind dem Lizenztext zu entnehmen.
*/
RELEASE_REGEX = /\d+.\d+.\d+/
SNAPSHOT_REGEX = /\d+.\d+.\d+-SNAPSHOT/
FAILED_STAGE = ""
SH_SUCCESS_STATUS_CODE = 0
KEYCLOAK_OPERATOR_NAME = 'ozgcloud-keycloak-operator'
ELASTICSEARCH_OPERATOR_NAME = 'ozgcloud-elasticsearch-operator'
}
options {
timeout(time: 1, unit: 'HOURS')
disableConcurrentBuilds()
buildDiscarder(logRotator(numToKeepStr: '10'))
}
stages {
stage('Check Version') {
steps {
script {
FAILED_STAGE = env.STAGE_NAME
def rootPom = readMavenPom file: 'pom.xml'
def rootVersion = rootPom.version
if ( !isReleaseVersion([rootVersion])) {
error("Keine Release Version für Branch ${env.BRANCH_NAME}.")
}
} else {
if ( !isSnapshotVersion([rootVersion])) {
error("Keine Snapshot Version für Branch ${env.BRANCH_NAME}.")
}
}
}
}
}
stage('Set Version') {
when {
not {
anyOf {
branch 'release'
}
}
}
steps {
script {
FAILED_STAGE=env.STAGE_NAME
JAR_TAG = getPomVersion().replace("SNAPSHOT", "${env.BRANCH_NAME}-SNAPSHOT")
}
configFileProvider([configFile(fileId: 'maven-settings', variable: 'MAVEN_SETTINGS')]) {
sh "mvn -s $MAVEN_SETTINGS versions:set -DnewVersion=${JAR_TAG} -DprocessAllModules=true"
}
}
}
steps {
script {
FAILED_STAGE=env.STAGE_NAME
}
configFileProvider([configFile(fileId: 'maven-settings', variable: 'MAVEN_SETTINGS')]) {
sh 'mvn --version'
sh 'mvn -s $MAVEN_SETTINGS clean install -Dmaven.wagon.http.retryHandler.count=3'
withSonarQubeEnv('sonarqube-ozg-sh'){
sh 'mvn -s $MAVEN_SETTINGS sonar:sonar'
}
}
} catch (Exception e) {
unstable("SonarQube failed")
}
}
}
}
post {
always{
junit testResults: '**/target/surefire-reports/*.xml', skipPublishingChecks: true
}
}
}
stage('Deploy to Nexus'){
steps {
script {
FAILED_STAGE = env.STAGE_NAME
}
configFileProvider([configFile(fileId: 'maven-settings', variable: 'MAVEN_SETTINGS')]) {
sh 'mvn -s $MAVEN_SETTINGS -DskipTests deploy'
sh "mvn -s $MAVEN_SETTINGS versions:revert"
stage('Build Docker image') {
steps {
script {
FAILED_STAGE=env.STAGE_NAME
}
configFileProvider([configFile(fileId: 'maven-settings', variable: 'MAVEN_SETTINGS')]) {
sh 'mvn -s $MAVEN_SETTINGS spring-boot:build-image -DskipTests -Dmaven.wagon.http.retryHandler.count=3'
stage('Tag and Push Docker image') {
steps {
script {
FAILED_STAGE=env.STAGE_NAME
IMAGE_TAG = generateImageTag()
tagAndPushDockerImage(KEYCLOAK_OPERATOR_NAME, IMAGE_TAG)
tagAndPushDockerImage(ELASTICSEARCH_OPERATOR_NAME, IMAGE_TAG)
tagAndPushDockerImage(KEYCLOAK_OPERATOR_NAME, 'snapshot-latest')
tagAndPushDockerImage(ELASTICSEARCH_OPERATOR_NAME, 'snapshot-latest')
else if (isReleaseBranch()) {
tagAndPushDockerImage(KEYCLOAK_OPERATOR_NAME, 'latest')
tagAndPushDockerImage(ELASTICSEARCH_OPERATOR_NAME, 'latest')
stage('Test, build and deploy Keycloak-Operator Helm Chart') {
testAndDeployKeycloakHelmChart(HELM_CHART_VERSION)
}
}
}
stage('Test, build and deploy Elasticsearch-Operator Helm Chart') {
steps {
script {
FAILED_STAGE=env.STAGE_NAME
testAndDeployElasticsearchHelmChart(HELM_CHART_VERSION)
stage('Trigger Dev rollout') {
when {
}
steps {
script {
FAILED_STAGE = env.STAGE_NAME
stage('Trigger Test rollout') {
when {
branch 'release'
}
steps {
script {
FAILED_STAGE = env.STAGE_NAME
Void testAndDeployKeycloakHelmChart(String helmChartVersion){
dir("${KEYCLOAK_OPERATOR_NAME}/src/main/helm") {
runHelmTests()
deployHelmChart(KEYCLOAK_OPERATOR_NAME, helmChartVersion)
}
}
Void testAndDeployElasticsearchHelmChart(String helmChartVersion){
dir("${ELASTICSEARCH_OPERATOR_NAME}/src/main/helm") {
deployHelmChart(ELASTICSEARCH_OPERATOR_NAME, helmChartVersion)
}
}
Void runHelmTests(){
sh 'helm lint -f ../../test/helm/linter_values.yaml'
sh "helm unittest -f '../../test/helm/*/*.yaml' ."
sh "helm package --version=${HELM_CHART_VERSION} ."
}
Void deployHelmChart(String helmChartName, String helmChartVersion) {
withCredentials([usernamePassword(credentialsId: 'jenkins-nexus-login', usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD')]){
def url = getHelmRepoUrl()
echo "Url: ${url}"
def result = sh script: '''curl -u $USERNAME:$PASSWORD ''' + url + ''' -F file=@'''+helmChartName+'''-'''+helmChartVersion+'''.tgz''', returnStdout: true
if (result != '') {
error(result)
}
}
}
String getHelmRepoUrl(){
if (isReleaseBranch()) {
return "https://nexus.ozg-sh.de/service/rest/v1/components?repository=ozg-base-apps"
}
return "https://nexus.ozg-sh.de/service/rest/v1/components?repository=ozg-base-apps-snapshot"
}
Boolean isMainBranch() {
return env.BRANCH_NAME == 'main'
Boolean isReleaseBranch() {
return env.BRANCH_NAME == 'release'
Void doDevRollout() {
cloneGitopsRepo()
setNewOperatorVersion('dev')
pushNewGitopsVersion('dev')
}
Void doTestRollout() {
cloneGitopsRepo()
setNewOperatorVersion('test')
pushNewGitopsVersion('test')
Void setNewOperatorVersion(String environment) {
dir('gitops') {
updateKeycloakOperatorVersions(environment)
updateElasticsearchOperatorVersions(environment)
Void updateKeycloakOperatorVersions(String environment){
def envFile = getApplicationValues(environment, KEYCLOAK_OPERATOR_NAME)
def envVersions = readYaml file: envFile
envVersions.ozgcloud_keycloak_operator.image.tag = IMAGE_TAG
envVersions.ozgcloud_keycloak_operator.helm.version = HELM_CHART_VERSION
writeYaml file: envFile, data: envVersions, overwrite: true
Void updateElasticsearchOperatorVersions(String environment){
def envFile = getApplicationValues(environment, ELASTICSEARCH_OPERATOR_NAME)
def envVersions = readYaml file: envFile
envVersions.ozgcloud_elasticsearch_operator.image.tag = IMAGE_TAG
envVersions.ozgcloud_elasticsearch_operator.helm.version = HELM_CHART_VERSION
writeYaml file: envFile, data: envVersions, overwrite: true
String getApplicationValues(String environment, String valuesFileName) {
return "${environment}/application/values/${valuesFileName}-values.yaml"
}
Void pushNewGitopsVersion(String environment) {
dir('gitops') {
return
}
withCredentials([usernamePassword(credentialsId: 'jenkins-gitea-access-token', passwordVariable: 'TOKEN', usernameVariable: 'USER')]) {
sh "git add ${environment}/application/values/ozgcloud-keycloak-operator-values.yaml"
sh "git add ${environment}/application/values/ozgcloud-elasticsearch-operator-values.yaml"
sh "git commit -m 'jenkins rollout ${environment} ozgcloud operators version ${IMAGE_TAG}'"
sh 'git push https://${USER}:${TOKEN}@git.ozg-sh.de/ozgcloud-devops/gitops.git'
return sh (script: "git status | grep '${environment}/application/values/ozgcloud-keycloak-operator-values.yaml'", returnStatus: true) == env.SH_SUCCESS_STATUS_CODE as Integer
}
Void configureGit() {
final email = "jenkins@ozg-sh.de"
final name = "jenkins"
dir("gitops") {
sh "git config user.email '${email}'"
sh "git config user.name '${name}'"
}
}
Void cloneGitopsRepo() {
withCredentials([usernamePassword(credentialsId: 'jenkins-gitea-access-token', passwordVariable: 'TOKEN', usernameVariable: 'USER')]) {
sh 'git clone https://${USER}:${TOKEN}@git.ozg-sh.de/ozgcloud-devops/gitops.git'
}
configureGit()
}
Void tagAndPushDockerImage(String imageName, String newTag){
withCredentials([usernamePassword(credentialsId: 'jenkins-nexus-login', usernameVariable: 'USER', passwordVariable: 'PASSWORD')]) {
sh 'docker login docker.ozg-sh.de -u ${USER} -p ${PASSWORD}'
sh "docker tag docker.ozg-sh.de/${imageName}:build-latest docker.ozg-sh.de/${imageName}:${newTag}"
sh "docker push docker.ozg-sh.de/${imageName}:${newTag}"
}
}
String generateImageTag() {
if (isReleaseBranch()) {
return getPomVersion()
}
return "${getPomVersion()}-${validateBranchName(env.BRANCH_NAME)}${getCommitHash()}".replaceAll("_", "-")
}
String getPomVersion(){
def pom = readMavenPom file: 'pom.xml'
String validateBranchName(branchName) {
int maxLength = 20
if (branchName.length() > maxLength) {
String originalBranchName = branchName
branchName = branchName.substring(0, maxLength)
echo "WARNING: Branch name '${originalBranchName}' exceeded ${maxLength} characters. " +
"It has been truncated to '${branchName}' for deployment purposes."
String getCommitHash() {
return "-${env.GIT_COMMIT.take(7)}";
}
String getParentPomVersion(String filePath) {
def pom = readMavenPom file: filePath
return pom.parent.version
}
Boolean isReleaseVersion(List versions) {
return matchRegexVersion(versions, RELEASE_REGEX)
}
Boolean isSnapshotVersion(List versions) {
return matchRegexVersion(versions, SNAPSHOT_REGEX)
}
Boolean matchRegexVersion(List versions, String regex) {
for (version in versions) {
if ( !(version ==~ regex) ) {
return false
}
}
return true