Files
rme-jenkins/Jenkinsfile
2026-08-18 21:17:51 +02:00

153 lines
6.8 KiB
Groovy
Executable File

def projects = ['ahtc', 'guez']
// Maps OsVersion -> BUILD_VERSION env var consumed by rpmbuild/make_rpm.py
// (the script looks for lts${BUILD_VERSION}.spec; empty selects specs/lts.spec).
// Ubuntu 26.04 is the target platform for Qt6 migration
def spec_suffix_for_os = [
'26.04': '26.04'
]
def choice_projects = ['ALL'] + projects
properties([
disableConcurrentBuilds(),
parameters([
choice(name: 'ProjectName', choices: choice_projects, description: 'LTS project flavor (passed as cmake -D_pname)'),
string(name: 'OsVersions', defaultValue: '26.04', description: 'Comma-separated Ubuntu base versions, all built in parallel (selects build container tag and spec variant)'),
string(name: 'LtsVersion', defaultValue: '1.0', description: 'LTS version (major.minor) passed to make_rpm.py --version'),
booleanParam(name: 'ClearWorkspace', defaultValue: false, description: 'Clear entire workspace on all nodes used for build'),
booleanParam(name: 'PublishArtifactRepo', defaultValue: true, description: 'Upload produced RPMs to the internal artifact repository')
])
])
env.GIT_TERMINAL_PROMPT = "0"
env.LTS_VERSION = "${params.LtsVersion}"
env.BUILD_CONTAINER_REGISTRY = "harbor.sl.defence-elec.de"
env.BUILD_CONTAINER_PREFIX = "buildcontainer"
env.ARTIFACTREPO = "https://internal-repo.sl.defence-elec.de"
env.BITBUCKET_URL = "https://devhub.defence-elec.de/bitbucket"
// Posts the build status to Bitbucket via jenkins/jenkins_notifier.sh (REST
// build-status API). A notification failure must never break the build itself.
def notifyBitbucketStatus(String state) {
try {
withCredentials([usernamePassword(credentialsId: 'bitbucket-notifier',
usernameVariable: 'CURL_USER',
passwordVariable: 'CURL_PASS')]) {
sh """
export CURL_CRED="\${CURL_USER}:\${CURL_PASS}"
export BUILD_STATE='${state}'
bash jenkins/jenkins_notifier.sh
"""
}
} catch (e) {
echo "WARNING: Bitbucket notification (${state}) failed: ${e.message}"
}
}
// OS versions this build covers; every (project, osVersion) pair runs in parallel.
def osVersions = params.OsVersions.split(',').collect { it.trim() }.findAll { it }
if (params.ProjectName != 'ALL') {
projects = [params.ProjectName]
}
// One parallel branch per (project, osVersion) combination. Outputs are isolated
// under rpms/${project}/${osVersion} so concurrent OS builds never collide.
def builds = [:]
projects.each { project ->
osVersions.each { osVersion ->
def buildVersion = spec_suffix_for_os.containsKey(osVersion) ? spec_suffix_for_os[osVersion] : osVersion
def rpmsDir = "rpms/${project}/${osVersion}"
builds["${project} (${osVersion})"] = {
stage("Prepare ${project} (${osVersion})") {
sh "rm -rf ${rpmsDir}"
sh "mkdir -p ${rpmsDir}"
}
stage("Build RPM ${project} (${osVersion})") {
def imageName = "${BUILD_CONTAINER_REGISTRY}/${BUILD_CONTAINER_PREFIX}/${project}_${osVersion}"
def buildContainer = docker.image("${imageName}")
def guezMode = (project == 'guez') ? 'ON' : 'OFF'
def dockerOpts = "--init --shm-size=2g" +
" -e HOME=/shd/CTC/TOOLS" +
" -e PROJECT_BASE_DIR=/tmp/legatus" +
" -e PROJECT=${project}" +
" -e OS_VERSION=${osVersion}" +
" -e LTS_VERSION=${LTS_VERSION}" +
" -e GUEZ_MODE=${guezMode}" +
" -e BUILD_VERSION=${buildVersion}" +
" -e BUILD_NUMBER=${env.BUILD_NUMBER}" +
" -e BUILD_TAG=${env.BUILD_TAG}"
buildContainer.inside(dockerOpts) {
sh "bash jenkins/jenkins_builder.sh"
}
}
stage("Publish ${project} (${osVersion})") {
if (params.PublishArtifactRepo) {
withCredentials([usernamePassword(credentialsId: 'internal-repo-uploader',
usernameVariable: 'CURL_USER',
passwordVariable: 'CURL_PASS')]) {
sh """
export CURL_CRED="\${CURL_USER}:\${CURL_PASS}"
export PROJECT='${project}'
export OS_VERSION='${osVersion}'
export LTS_VERSION='${LTS_VERSION}'
export BUILD_NUMBER='${env.BUILD_NUMBER}'
export ARTIFACTREPO='${env.ARTIFACTREPO}'
export ARTIFACTFOLDER='${project}'
bash jenkins/jenkins_publisher.sh
"""
}
def tdsUrl = readFile("url-${project}-${osVersion}.txt").trim()
def tdsVersion = readFile("tdsversion-${project}-${osVersion}.txt").trim()
def link = """<a href="${tdsUrl}" target="_blank">${project} ${tdsVersion} (OS ${osVersion})</a>"""
currentBuild.description = currentBuild.description ? "${currentBuild.description}<br/>${link}" : link
} else {
echo "Artifact-repo publish skipped for ${project} (OS ${osVersion}, PublishArtifactRepo=false)"
}
}
stage("Cleanup ${project} (${osVersion})") {
sh "rm -rf ${rpmsDir}"
}
}
}
}
notifyBitbucketStatus('INPROGRESS')
try {
stage("Initialization") {
if (params.ClearWorkspace) {
cleanWs()
checkout([
$class: 'GitSCM',
branches: scm.branches,
doGenerateSubmoduleConfigurations: false,
extensions: [[$class: 'SubmoduleOption', disableSubmodules: false, parentCredentials: true, recursiveSubmodules: true, reference: '', trackingSubmodules: false]],
userRemoteConfigs: scm.userRemoteConfigs
])
}
echo "Legatus build initialized — branch '${env.BRANCH_NAME}', project(s): ${projects.join(', ')}, LTS ${env.LTS_VERSION}, OS version(s) (parallel): ${osVersions.join(', ')}"
}
parallel builds
stage("Finalization") {
echo "Legatus build completed — branch '${env.BRANCH_NAME}', project(s): ${projects.join(', ')} (LTS ${env.LTS_VERSION}), OS version(s): ${osVersions.join(', ')}"
}
currentBuild.result = 'SUCCESS'
} catch (e) {
currentBuild.result = 'FAILURE'
throw e
} finally {
notifyBitbucketStatus(currentBuild.result == 'SUCCESS' ? 'SUCCESSFUL' : 'FAILED')
}