1+ // Copyright (c) 2024-2025 Progress Software Corporation and/or its subsidiaries or affiliates. All Rights Reserved.
2+
13/* groovylint-disable CompileStatic, LineLength, VariableTypeRequired */
24// This Jenkinsfile defines internal MarkLogic build pipeline.
35
68import groovy.json.JsonSlurperClassic
79
810emailList = ' vitaly.korolev@progress.com, sumanth.ravipati@progress.com, peng.zhou@progress.com, barkha.choithani@progress.com, romain.winieski@progress.com'
9- emailSecList = ' Rangan.Doreswamy@progress.com, Mahalakshmi.Srinivasan@progress.com'
11+ emailSecList = ' Mahalakshmi.Srinivasan@progress.com'
1012gitCredID = ' marklogic-builder-github'
13+ operatorRegistry = ' ml-marklogic-operator-dev.bed-artifactory.bedford.progress.com'
1114JIRA_ID = ' '
1215JIRA_ID_PATTERN = / (?i)(MLE)-\d {3,6}/
16+ operatorRepo = ' marklogic-kubernetes-operator'
17+ timeStamp = new Date (). format(' yyyyMMdd' )
18+ branchNameTag = env. BRANCH_NAME . replaceAll(' /' , ' -' )
1319
1420// Define local funtions
1521void preBuildCheck () {
@@ -35,6 +41,7 @@ void preBuildCheck() {
3541 }
3642
3743 // our VMs sometimes disable bridge traffic. this should help to restore it.
44+ sh ' sudo modprobe br_netfilter'
3845 sh ' sudo sh -c "echo 1 > /proc/sys/net/bridge/bridge-nf-call-iptables"'
3946}
4047
@@ -92,7 +99,7 @@ def getReviewState() {
9299 return reviewState
93100}
94101
95- void resultNotification (message ) {
102+ void resultNotification (status ) {
96103 def author, authorEmail, emailList
97104 // add author of a PR to email list if available
98105 if (env. CHANGE_AUTHOR ) {
@@ -107,11 +114,11 @@ void resultNotification(message) {
107114 jira_email_body = " ${ email_body} <br><br><b>Jira URL: </b><br><a href='${ jira_link} '>${ jira_link} </a>"
108115
109116 if (JIRA_ID ) {
110- def comment = [ body : " Jenkins pipeline build result: ${ message } " ]
117+ def comment = [ body : " Jenkins pipeline build result: ${ status } " ]
111118 jiraAddComment site : ' JIRA' , idOrKey : JIRA_ID , failOnError : false , input : comment
112- mail charset : ' UTF-8' , mimeType : ' text/html' , to : " ${ emailList} " , body : " ${ jira_email_body} " , subject : " ${ message } : ${ env.JOB_NAME} #${ env.BUILD_NUMBER} - ${ JIRA_ID} "
119+ mail charset : ' UTF-8' , mimeType : ' text/html' , to : " ${ emailList} " , body : " ${ jira_email_body} " , subject : " 🥷 ${ status } : ${ env.JOB_NAME} #${ env.BUILD_NUMBER} - ${ JIRA_ID} "
113120 } else {
114- mail charset : ' UTF-8' , mimeType : ' text/html' , to : " ${ emailList} " , body : " ${ email_body} " , subject : " ${ message } : ${ env.JOB_NAME} #${ env.BUILD_NUMBER} "
121+ mail charset : ' UTF-8' , mimeType : ' text/html' , to : " ${ emailList} " , body : " ${ email_body} " , subject : " 🥷 ${ status } : ${ env.JOB_NAME} #${ env.BUILD_NUMBER} "
115122 }
116123}
117124
@@ -125,15 +132,15 @@ void runTests() {
125132}
126133
127134void runMinikubeSetup () {
128- sh '''
129- make e2e-setup-minikube
130- '''
135+ sh """
136+ make e2e-setup-minikube IMG= ${ operatorRepo } : ${ VERSION }
137+ """
131138}
132139
133140void runE2eTests () {
134- sh '''
135- make e2e-test
136- '''
141+ sh """
142+ make e2e-test IMG= ${ operatorRepo } : ${ VERSION }
143+ """
137144}
138145
139146void runMinikubeCleanup () {
@@ -142,6 +149,43 @@ void runMinikubeCleanup() {
142149 '''
143150}
144151
152+ void runBlackDuckScan () {
153+ // Trigger BlackDuck scan job with CONTAINER_IMAGES parameter when params.PUBLISH_IMAGE is true
154+ if (params. PUBLISH_IMAGE ) {
155+ build job : ' securityscans/Blackduck/KubeNinjas/kubernetes-operator' , wait : false , parameters : [ string(name : ' branch' , value : " ${ env.BRANCH_NAME} " ), string(name : ' CONTAINER_IMAGES' , value : " ${ operatorRegistry} /${ operatorRepo} :${ VERSION} -${ branchNameTag} -${ timeStamp} " ) ]
156+ } else {
157+ build job : ' securityscans/Blackduck/KubeNinjas/kubernetes-operator' , wait : false , parameters : [ string(name : ' branch' , value : " ${ env.BRANCH_NAME} " ) ]
158+ }
159+ }
160+
161+ /**
162+ * Publishes the built Docker image to the internal Artifactory registry.
163+ * Tags the image with multiple tags (version-specific, branch-specific, latest).
164+ * Requires Artifactory credentials.
165+ */
166+ void publishToInternalRegistry () {
167+ withCredentials([usernamePassword(credentialsId : ' builder-credentials-artifactory' , passwordVariable : ' docker_password' , usernameVariable : ' docker_user' )]) {
168+
169+ sh """
170+ # make sure to logout first to avoid issues with cached credentials
171+ docker logout ${ operatorRegistry}
172+ echo "${ docker_password} " | docker login --username ${ docker_user} --password-stdin ${ operatorRegistry}
173+
174+ # Create tags
175+ docker tag ${ operatorRepo} :${ VERSION} ${ operatorRegistry} /${ operatorRepo} :${ VERSION}
176+ docker tag ${ operatorRepo} :${ VERSION} ${ operatorRegistry} /${ operatorRepo} :${ VERSION} -${ branchNameTag}
177+ docker tag ${ operatorRepo} :${ VERSION} ${ operatorRegistry} /${ operatorRepo} :${ VERSION} -${ branchNameTag} -${ timeStamp}
178+ docker tag ${ operatorRepo} :${ VERSION} ${ operatorRegistry} /${ operatorRepo} :latest
179+
180+ # Push images to internal registry
181+ docker push ${ operatorRegistry} /${ operatorRepo} :${ VERSION}
182+ docker push ${ operatorRegistry} /${ operatorRepo} :${ VERSION} -${ branchNameTag}
183+ docker push ${ operatorRegistry} /${ operatorRepo} :${ VERSION} -${ branchNameTag} -${ timeStamp}
184+ docker push ${ operatorRegistry} /${ operatorRepo} :latest
185+ """
186+ }
187+ }
188+
145189pipeline {
146190 agent {
147191 label {
@@ -153,15 +197,25 @@ pipeline {
153197 buildDiscarder logRotator(artifactDaysToKeepStr : ' 20' , artifactNumToKeepStr : ' ' , daysToKeepStr : ' 30' , numToKeepStr : ' ' )
154198 skipStagesAfterUnstable()
155199 }
156- // triggers {
157- // //TODO: add scheduled runs
158- // }
159- // environment {
160- // //TODO
161- // }
200+
201+ triggers {
202+ // Trigger nightly builds on the develop branch
203+ parameterizedCron( env. BRANCH_NAME == ' develop' ? ''' 00 05 * * * % E2E_MARKLOGIC_IMAGE_VERSION=ml-docker-db-dev-tierpoint.bed-artifactory.bedford.progress.com/marklogic/marklogic-server-ubi-rootless:latest-12
204+ 00 05 * * * % E2E_MARKLOGIC_IMAGE_VERSION=ml-docker-db-dev-tierpoint.bed-artifactory.bedford.progress.com/marklogic/marklogic-server-ubi-rootless:latest-11; PUBLISH_IMAGE=false''' : ' ' )
205+ }
206+
207+ environment {
208+ PATH = " /space/go/bin:${ env.PATH} "
209+ MINIKUBE_HOME = " /space/minikube/"
210+ KUBECONFIG = " /space/.kube-config"
211+ GOPATH = " /space/go"
212+ }
213+
162214
163215 parameters {
164- string(name : ' dockerImage' , defaultValue : ' ml-docker-db-dev-tierpoint.bed-artifactory.bedford.progress.com/marklogic/marklogic-server-ubi:latest-11' , description : ' Docker image to use for tests.' , trim : true )
216+ string(name : ' E2E_MARKLOGIC_IMAGE_VERSION' , defaultValue : ' ml-docker-db-dev-tierpoint.bed-artifactory.bedford.progress.com/marklogic/marklogic-server-ubi-rootless:latest-12' , description : ' Docker image to use for tests.' , trim : true )
217+ string(name : ' VERSION' , defaultValue : ' 1.1.0' , description : ' Version to tag the image with.' , trim : true )
218+ booleanParam(name : ' PUBLISH_IMAGE' , defaultValue : false , description : ' Publish image to internal registry' )
165219 string(name : ' emailList' , defaultValue : emailList, description : ' List of email for build notification' , trim : true )
166220 }
167221
@@ -195,6 +249,26 @@ pipeline {
195249 runMinikubeCleanup()
196250 }
197251 }
252+
253+ // Publish image to internal registries (conditional)
254+ stage(' Publish Image' ) {
255+ when {
256+ anyOf {
257+ branch ' develop'
258+ expression { return params. PUBLISH_IMAGE }
259+ }
260+ }
261+ steps {
262+ publishToInternalRegistry()
263+ }
264+ }
265+
266+ stage(' Run-BlackDuck-Scan' ) {
267+
268+ steps {
269+ runBlackDuckScan()
270+ }
271+ }
198272
199273 }
200274
@@ -203,13 +277,16 @@ pipeline {
203277 publishTestResults()
204278 }
205279 success {
206- resultNotification(' BUILD SUCCESS ✅ ' )
280+ resultNotification(' ✅ Success ' )
207281 }
208282 failure {
209- resultNotification(' BUILD ERROR ❌ ' )
283+ resultNotification(' ❌ Failure ' )
210284 }
211285 unstable {
212- resultNotification(' BUILD UNSTABLE 🉑' )
286+ resultNotification(' ⚠️ Unstable' )
287+ }
288+ aborted {
289+ resultNotification(' 🚫 Aborted' )
213290 }
214291 }
215292}
0 commit comments