From 667c03139d3b15997ae7005abe020a65461b2f85 Mon Sep 17 00:00:00 2001 From: Vitaly Korolev Date: Thu, 23 Oct 2025 10:50:54 -0700 Subject: [PATCH 1/3] Add publishing step and enable scheduled builds --- Jenkinsfile | 72 +++++++++++++++++++++++++++++++++++++++++++---------- Makefile | 2 +- 2 files changed, 60 insertions(+), 14 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 855dd71..97f3843 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -8,8 +8,10 @@ import groovy.json.JsonSlurperClassic emailList = 'vitaly.korolev@progress.com, sumanth.ravipati@progress.com, peng.zhou@progress.com, barkha.choithani@progress.com, romain.winieski@progress.com' emailSecList = 'Mahalakshmi.Srinivasan@progress.com' gitCredID = 'marklogic-builder-github' +operatorRegistry = 'ml-marklogic-operator-dev.bed-artifactory.bedford.progress.com' JIRA_ID = '' JIRA_ID_PATTERN = /(?i)(MLE)-\d{3,6}/ +operatorRepo = 'marklogic-kubernetes-operator' // Define local funtions void preBuildCheck() { @@ -126,15 +128,15 @@ void runTests() { } void runMinikubeSetup() { - sh ''' - make e2e-setup-minikube - ''' + sh """ + make e2e-setup-minikube IMG=${operatorRepo}:${VERSION} + """ } void runE2eTests() { - sh ''' - make e2e-test - ''' + sh """ + make e2e-test IMG=${operatorRepo}:${VERSION} + """ } void runMinikubeCleanup() { @@ -146,6 +148,36 @@ void runMinikubeCleanup() { void runSecurityScan() { build job: 'securityscans/Blackduck/KubeNinjas/kubernetes-operator', wait: false, parameters: [ string(name: 'branch', value: "${env.BRANCH_NAME}") ] } + +/** + * Publishes the built Docker image to the internal Artifactory registry. + * Tags the image with multiple tags (version-specific, branch-specific, latest). + * Requires Artifactory credentials. + */ +void publishToInternalRegistry() { + withCredentials([usernamePassword(credentialsId: 'builder-credentials-artifactory', passwordVariable: 'docker_password', usernameVariable: 'docker_user')]) { + timeStamp = new Date().format('yyyyMMdd') + branchNameTag = env.BRANCH_NAME.replaceAll('/', '-') + sh """ + # make sure to logout first to avoid issues with cached credentials + docker logout ${operatorRegistry} + echo "${docker_password}" | docker login --username ${docker_user} --password-stdin ${operatorRegistry} + + # Create tags + docker tag ${operatorRepo}:${VERSION} ${operatorRegistry}/${operatorRepo}:${VERSION} + docker tag ${operatorRepo}:${VERSION} ${operatorRegistry}/${operatorRepo}:${VERSION}-${branchNameTag} + docker tag ${operatorRepo}:${VERSION} ${operatorRegistry}/${operatorRepo}:${VERSION}-${branchNameTag}-${timeStamp} + docker tag ${operatorRepo}:${VERSION} ${operatorRegistry}/${operatorRepo}:latest + + # Push images to internal registry + docker push ${operatorRegistry}/${operatorRepo}:${VERSION} + docker push ${operatorRegistry}/${operatorRepo}:${VERSION}-${branchNameTag} + docker push ${operatorRegistry}/${operatorRepo}:${VERSION}-${branchNameTag}-${timeStamp} + docker push ${operatorRegistry}/${operatorRepo}:latest + """ + } +} + pipeline { agent { label { @@ -157,16 +189,17 @@ pipeline { buildDiscarder logRotator(artifactDaysToKeepStr: '20', artifactNumToKeepStr: '', daysToKeepStr: '30', numToKeepStr: '') skipStagesAfterUnstable() } - // triggers { - // //TODO: add scheduled runs - // } - // environment { - // //TODO - // } + + triggers { + // Trigger nightly builds on the develop branch + 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 + 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''' : '') + } parameters { 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) - string(name: 'IMG', defaultValue: 'testrepo/marklogic-operator-image-dev:internal', description: 'Docker image for Running Operator Container', trim: true) + string(name: 'VERSION', defaultValue: '1.1.0', description: 'Version to tag the image with.', trim: true) + booleanParam(name: 'PUBLISH_IMAGE', defaultValue: false, description: 'Publish image to internal registry') string(name: 'emailList', defaultValue: emailList, description: 'List of email for build notification', trim: true) } @@ -206,6 +239,19 @@ pipeline { runMinikubeCleanup() } } + + // Publish image to internal registries (conditional) + stage('Publish Image') { + when { + anyOf { + branch 'develop' + expression { return params.PUBLISH_IMAGE } + } + } + steps { + publishToInternalRegistry() + } + } } diff --git a/Makefile b/Makefile index de1ee0c..6267307 100644 --- a/Makefile +++ b/Makefile @@ -66,7 +66,7 @@ OPERATOR_SDK_VERSION ?= v1.34.2 # Image URL to use all building/pushing image targets # Image for dev: ml-marklogic-operator-dev.bed-artifactory.bedford.progress.com/marklogic-operator-kubernetes # IMG ?= progressofficial/marklogic-operator-kubernetes:$(VERSION) -IMG = "testrepo/marklogic-operator-image-dev:1.0.0" +IMG ?= "testrepo/marklogic-operator-image-dev:1.0.0" # Get the currently used golang install path (in GOPATH/bin, unless GOBIN is set) From 2989f6504618dc15d23baf02ea2fe8c67d10388c Mon Sep 17 00:00:00 2001 From: Vitaly Korolev Date: Thu, 23 Oct 2025 14:14:25 -0700 Subject: [PATCH 2/3] move blackduck scan after publishing --- Jenkinsfile | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 97f3843..a434224 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -145,8 +145,8 @@ void runMinikubeCleanup() { ''' } -void runSecurityScan() { - build job: 'securityscans/Blackduck/KubeNinjas/kubernetes-operator', wait: false, parameters: [ string(name: 'branch', value: "${env.BRANCH_NAME}") ] +void runBlackDuckScan() { + build job: 'securityscans/Blackduck/KubeNinjas/kubernetes-operator', wait: false, parameters: [ string(name: 'branch', value: "${env.BRANCH_NAME}"), string(name: 'CONTAINER_IMAGES', value: "${operatorRepo}:${VERSION}-${branchNameTag}") ] } /** @@ -210,12 +210,6 @@ pipeline { } } - stage('Run-Security-Scan') { - steps { - runSecurityScan() - } - } - stage('Run-tests') { steps { runTests() @@ -252,6 +246,17 @@ pipeline { publishToInternalRegistry() } } + + stage('Run-BlackDuck-Scan') { + when { + anyOf { + expression { return params.PUBLISH_IMAGE } + } + } + steps { + runBlackDuckScan() + } + } } From ab65db62b6254734e3e69f03085a68e257a5e82a Mon Sep 17 00:00:00 2001 From: Vitaly Korolev Date: Thu, 23 Oct 2025 14:20:14 -0700 Subject: [PATCH 3/3] Ensure we run container scan when we publish, otherwise just the source --- Jenkinsfile | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index a434224..6e4ef4f 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -12,6 +12,8 @@ operatorRegistry = 'ml-marklogic-operator-dev.bed-artifactory.bedford.progress.c JIRA_ID = '' JIRA_ID_PATTERN = /(?i)(MLE)-\d{3,6}/ operatorRepo = 'marklogic-kubernetes-operator' +timeStamp = new Date().format('yyyyMMdd') +branchNameTag = env.BRANCH_NAME.replaceAll('/', '-') // Define local funtions void preBuildCheck() { @@ -146,7 +148,12 @@ void runMinikubeCleanup() { } void runBlackDuckScan() { - build job: 'securityscans/Blackduck/KubeNinjas/kubernetes-operator', wait: false, parameters: [ string(name: 'branch', value: "${env.BRANCH_NAME}"), string(name: 'CONTAINER_IMAGES', value: "${operatorRepo}:${VERSION}-${branchNameTag}") ] + // Trigger BlackDuck scan job with CONTAINER_IMAGES parameter when params.PUBLISH_IMAGE is true + if (params.PUBLISH_IMAGE) { + build job: 'securityscans/Blackduck/KubeNinjas/kubernetes-operator', wait: false, parameters: [ string(name: 'branch', value: "${env.BRANCH_NAME}"), string(name: 'CONTAINER_IMAGES', value: "${operatorRepo}:${VERSION}-${branchNameTag}") ] + } else { + build job: 'securityscans/Blackduck/KubeNinjas/kubernetes-operator', wait: false, parameters: [ string(name: 'branch', value: "${env.BRANCH_NAME}") ] + } } /** @@ -156,8 +163,7 @@ void runBlackDuckScan() { */ void publishToInternalRegistry() { withCredentials([usernamePassword(credentialsId: 'builder-credentials-artifactory', passwordVariable: 'docker_password', usernameVariable: 'docker_user')]) { - timeStamp = new Date().format('yyyyMMdd') - branchNameTag = env.BRANCH_NAME.replaceAll('/', '-') + sh """ # make sure to logout first to avoid issues with cached credentials docker logout ${operatorRegistry} @@ -248,11 +254,7 @@ pipeline { } stage('Run-BlackDuck-Scan') { - when { - anyOf { - expression { return params.PUBLISH_IMAGE } - } - } + steps { runBlackDuckScan() }