From e9c2a43b9de66ad9c640a99d2f3dba9e422f330b Mon Sep 17 00:00:00 2001 From: caviedesj Date: Fri, 16 Jan 2026 10:24:43 +0100 Subject: [PATCH] Feat 11077. Self-contained repos: new Jenkins pipeline Change-Id: I3a815a2d65db19757913630ba12236c4271ed76f Signed-off-by: caviedesj --- Jenkinsfile.new | 189 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 189 insertions(+) create mode 100644 Jenkinsfile.new diff --git a/Jenkinsfile.new b/Jenkinsfile.new new file mode 100644 index 000000000..eb0aacba3 --- /dev/null +++ b/Jenkinsfile.new @@ -0,0 +1,189 @@ +/* + 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, either express or + implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +def DEFAULT_MODULE_NAME = 'devops' + +pipeline { + agent { label 'pool' } + options { disableConcurrentBuilds() } + parameters { + // Core Gerrit / multibranch inputs + string(name: 'GERRIT_BRANCH', defaultValue: env.BRANCH_NAME ?: 'master', description: '') + string(name: 'GERRIT_PROJECT', defaultValue: 'osm/devops', description: '') + string(name: 'GERRIT_REFSPEC', defaultValue: env.GERRIT_REFSPEC ?: '', description: '') + string(name: 'GERRIT_PATCHSET_REVISION', defaultValue: env.GERRIT_PATCHSET_REVISION ?: '', description: '') + string(name: 'DOCKER_ARGS', defaultValue: '', description: 'Extra docker args for docker run') + + // E2E test parameters + string(name: 'OPENSTACK_BASE_IMAGE', defaultValue: 'ubuntu22.04', description: '') + string(name: 'OPENSTACK_OSM_FLAVOR', defaultValue: 'osm.sanity', description: '') + string(name: 'MODULE_NAME', defaultValue: 'devops', description: 'Name of the module under test') + + // Pipeline control flags + booleanParam(name: 'DO_INSTALL', defaultValue: true, description: '') + booleanParam(name: 'DO_DOCKERPUSH', defaultValue: true, description: '') + booleanParam(name: 'DO_ROBOT', defaultValue: true, description: '') + booleanParam(name: 'SAVE_CONTAINER_ON_FAIL', defaultValue: false, description: '') + booleanParam(name: 'SAVE_CONTAINER_ON_PASS', defaultValue: false, description: '') + + // Docker image configuration + string(name: 'IMAGENAME', defaultValue: 'opensourcemano/devops', description: 'Image name for publish (reserved)') + } + environment { + MDG = "${params.GERRIT_PROJECT?.contains('/') ? params.GERRIT_PROJECT.split('/')[1] : params.GERRIT_PROJECT}" + CONTAINER_NAME = "${params.GERRIT_PROJECT}-${params.GERRIT_BRANCH}".toLowerCase() + TEST_IMAGE = 'overdrive3000/tox-osm:v1.6' + DOCKER_REGISTRY = 'osm.etsi.org:5050/devops/cicd/' + } + stages { + stage('Prepare') { steps { sh 'env' } } + + stage('Checkout') { + steps { + checkout scm + script { + sh "git fetch --tags" + if (params.GERRIT_REFSPEC?.trim()) { sh "git fetch origin ${params.GERRIT_REFSPEC}" } + if (params.GERRIT_PATCHSET_REVISION?.trim()) { sh "git checkout -f ${params.GERRIT_PATCHSET_REVISION}" } + sh "sudo git clean -dfx || git clean -dfx" + } + } + } + + stage('License Scan') { + steps { + script { + def isMergeJob = env.JOB_NAME?.contains('merge') + if (!isMergeJob) { sh 'devops/tools/license_scan.sh' } else { echo 'skip the scan for merge' } + } + } + } + + stage('Prepare Test Image') { + steps { + script { + // Use shared test image from registry; no local build needed + sh "docker pull ${env.TEST_IMAGE} || true" + } + } + } + + stage('Tests') { + steps { + script { + def UID = sh(returnStdout: true, script: 'id -u').trim() + def GID = sh(returnStdout: true, script: 'id -g').trim() + def common = "-v ${env.WORKSPACE}:/tests -e UID=${UID} -e GID=${GID} " + (params.DOCKER_ARGS ?: '') + + stage('Helm Tests') { + sh """ + docker run --rm ${common} \ + ${env.TEST_IMAGE} \ + /tests/devops-stages/stage-test.sh + """ + if (fileExists('coverage.xml')) { cobertura coberturaReportFile: 'coverage.xml' } + if (fileExists('nosetests.xml')) { junit 'nosetests.xml' } + } + + stage('Changelog') { + sh 'mkdir -p changelog' + sh """ + docker run --rm ${common} \ + ${env.TEST_IMAGE} \ + /bin/sh -lc 'devops/tools/generatechangelog-pipeline.sh > /tests/changelog/changelog-${MDG}.html' + """ + } + } + } + } + + stage('Build & Push Image') { + when { expression { return params.DO_DOCKERPUSH } } + steps { + script { + def moduleName = (env.MDG ?: DEFAULT_MODULE_NAME).toLowerCase() + + if (!params.GERRIT_BRANCH) { + error 'GERRIT_BRANCH is required to tag the Docker image' + } + def sanitizedBranchName = params.GERRIT_BRANCH + .toLowerCase() + .replaceAll('[^a-z0-9._-]', '-') + def baseTagPrefix = "osm-${sanitizedBranchName}" + def buildNumber = env.BUILD_NUMBER ?: '0' + def isMergeJob = env.JOB_NAME?.contains('merge') + // Remove promotion logic from this stage + def moduleTags = [] + if (isMergeJob) { + moduleTags << "${baseTagPrefix}-merge-${buildNumber}" + } else { + moduleTags << "${baseTagPrefix}-patchset-${buildNumber}" + } + + def imageName = params.IMAGENAME ?: "opensourcemano/${moduleName}" + def primaryLocalImage = "${imageName}:${moduleTags[0]}" + + withCredentials([[$class: 'UsernamePasswordMultiBinding', credentialsId: 'gitlab-registry', + usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD']]) { + sh """ + docker build -f Dockerfile -t ${primaryLocalImage} . + """ + sh "docker login ${env.DOCKER_REGISTRY.split('/')[0]} -u ${USERNAME} -p ${PASSWORD}" + // Push build-scope tag(s) only. Promotion happens after tests. + moduleTags.each { tag -> + def localImage = "${imageName}:${tag}" + def remoteImage = "${env.DOCKER_REGISTRY}${imageName}:${tag}" + sh "docker tag ${localImage} ${remoteImage}" + sh "docker push ${remoteImage}" + } + // Stash the built image id for later promotion without rebuild + env.BUILT_IMAGE = primaryLocalImage + env.BUILT_TAG = moduleTags[0] + } + } + } + } + + stage('E2E Test (robot)') { + when { expression { return params.DO_ROBOT && !env.JOB_NAME.contains('merge') } } + steps { + script { + def dowstreamJob = "osm-e2e/${params.GERRIT_BRANCH ?: 'master'}" + build job: dowstreamJob, + parameters: [ + string(name: 'GERRIT_BRANCH', value: params.GERRIT_BRANCH ?: 'master'), + string(name: 'GERRIT_REFSPEC', value: params.GERRIT_REFSPEC ?: ''), + string(name: 'OPENSTACK_BASE_IMAGE', value: params.OPENSTACK_BASE_IMAGE), + string(name: 'OPENSTACK_OSM_FLAVOR', value: params.OPENSTACK_OSM_FLAVOR), + string(name: 'MODULE_NAME', value: params.MODULE_NAME ?: 'devops'), + string(name: 'CONTAINER_NAME', value: env.BUILT_TAG), + booleanParam(name: 'DO_ROBOT', value: params.DO_ROBOT), + booleanParam(name: 'DO_INSTALL', value: params.DO_INSTALL), + booleanParam(name: 'SAVE_CONTAINER_ON_FAIL', value: params.SAVE_CONTAINER_ON_FAIL), + booleanParam(name: 'SAVE_CONTAINER_ON_PASS', value: params.SAVE_CONTAINER_ON_PASS) + ] + } + } + } + } + + post { + always { + // cleanWs() + deleteDir() + } + } +} + -- 2.25.1