From cf9a50d3add362cdf629019eb834c64279e7e593 Mon Sep 17 00:00:00 2001 From: Vitaly Korolev Date: Thu, 30 Jul 2026 07:14:45 -1000 Subject: [PATCH 1/2] MLE-31723: Use exact tag in Publish-Image to prevent wrong image publish --- Jenkinsfile | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 2ca1e8f..ceeaff7 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -767,6 +767,9 @@ pipeline { script { unstash 'built-image-archive' // Load image from tar if not already available (applies to all build types) + // Node's Docker daemon is shared with other concurrent builds, so only ever + // trust the exact, fully-qualified tag - never a loose repo/type match, which + // could resolve to a different build's image (e.g. a different marklogicVersion). sh """ if ! docker image inspect ${builtImage} &>/dev/null; then echo "Image not found locally, loading from ${WORKSPACE}/${GRAVITON3_IMAGE_ARCHIVE}..." @@ -774,23 +777,11 @@ pipeline { else echo "Image ${builtImage} already available locally" fi + docker image inspect ${builtImage} >/dev/null """ - - // If builtImage doesn't exist, find the loaded image by repo pattern - def actualImage = sh( - returnStdout: true, - script: """docker images --format 'table {{.Repository}}:{{.Tag}}' | grep "marklogic/marklogic-server-${dockerImageType}:" | head -1""" - ).trim() - - if (!actualImage) { - actualImage = builtImage - echo "Using builtImage tag: ${actualImage}" - } else { - echo "Found loaded image: ${actualImage}" - } - + // Store for use in publishToInternalRegistry - env.IMAGE_TO_PUBLISH = actualImage + env.IMAGE_TO_PUBLISH = builtImage } publishToInternalRegistry() // Trigger downstream QA image build job From 515cdfb738f15819683816ddfa719b0f3c68e50b Mon Sep 17 00:00:00 2001 From: barkhachoithani Date: Fri, 31 Jul 2026 13:35:46 -0700 Subject: [PATCH 2/2] fix(jenkins): prevent concurrent 11/12 builds from cross-selecting RPMs and publishing wrong image versions --- Jenkinsfile | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index ceeaff7..d95418b 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -274,12 +274,28 @@ void copyRPMs() { fi """ script { - // Get the RPM and Converters file names for the correct architecture (archSuffix already defined above) - // Use newest files so we don't accidentally pick a stale RPM left from a previous run. - RPM = sh(returnStdout: true, script: "cd src; ls -1t MarkLogic-*.${archSuffix}.rpm 2>/dev/null | head -1").trim() - CONVERTERS = sh(returnStdout: true, script: "cd src; (ls -1t MarkLogicConverters-*.${archSuffix}.rpm 2>/dev/null || ls -1t MarkLogicConverters-*.rpm 2>/dev/null) | head -1").trim() + // Select RPMs using version-specific patterns first to avoid picking another concurrent build's artifacts. + RPM = sh(returnStdout: true, script: "cd src; ls -1t MarkLogic-${RPMversion}*.${archSuffix}.rpm 2>/dev/null | head -1").trim() + if (!RPM) { + RPM = sh(returnStdout: true, script: "cd src; ls -1t MarkLogic-*.${archSuffix}.rpm 2>/dev/null | head -1").trim() + } + + CONVERTERS = sh(returnStdout: true, script: "cd src; ls -1t MarkLogicConverters-${RPMversion}*.${archSuffix}.rpm 2>/dev/null | head -1").trim() + if (!CONVERTERS) { + CONVERTERS = sh(returnStdout: true, script: "cd src; (ls -1t MarkLogicConverters-*.${archSuffix}.rpm 2>/dev/null || ls -1t MarkLogicConverters-*.rpm 2>/dev/null) | head -1").trim() + } + + if (!RPM) { + error "No MarkLogic RPM found in src/ for architecture ${archSuffix}" + } + // Extract MarkLogic version from RPM file name (handle both x86_64 and aarch64) marklogicVersion = sh(returnStdout: true, script: "echo ${RPM} | awk -F 'MarkLogic-' '{print \$2;}' | awk -F '.x86_64.rpm' '{print \$1;}' | awk -F '.aarch64.rpm' '{print \$1;}' | awk -F '-rhel' '{print \$1;}'").trim() + + if (!marklogicVersion.startsWith("${params.marklogicVersion}.")) { + error "Resolved RPM version '${marklogicVersion}' does not match requested marklogicVersion '${params.marklogicVersion}'" + } + echo "Selected server RPM: ${RPM}" echo "Selected converters RPM: ${CONVERTERS}" echo "Derived MarkLogic version from RPM: ${marklogicVersion}"