Commit 3ccebf92 authored by Dominik Charousset's avatar Dominik Charousset

Follow Groovy coding style and archive builds

parent da9956ac
#!/usr/bin/env groovy #!/usr/bin/env groovy
// List of CMake arguments used by most builds. // Default CMake flags for most builds (except coverage).
defaultCmakeArgs = '-DCAF_MORE_WARNINGS:BOOL=yes' \ defaultBuildFlags = [
+ ' -DCAF_ENABLE_RUNTIME_CHECKS:BOOL=yes' \ 'CAF_MORE_WARNINGS:BOOL=yes',
+ ' -DOPENSSL_ROOT_DIR=/usr/local/opt/openssl' \ 'CAF_ENABLE_RUNTIME_CHECKS:BOOL=yes',
+ ' -DOPENSSL_INCLUDE_DIR=/usr/local/opt/openssl/include' \ 'CAF_NO_OPENCL:BOOL=yes',
'OPENSSL_ROOT_DIR=/usr/local/opt/openssl',
'OPENSSL_INCLUDE_DIR=/usr/local/opt/openssl/include',
]
// CMake flags for release builds.
releaseBuildFlags = defaultBuildFlags + [
]
// CMake flags for debug builds.
debugBuildFlags = defaultBuildFlags + [
'CAF_ENABLE_RUNTIME_CHECKS:BOOL=yes',
'CAF_ENABLE_ADDRESS_SANITIZER:BOOL=yes',
'CAF_LOG_LEVEL:STRING=4',
]
// Our build matrix. The keys are the operating system labels and the values // Our build matrix. The keys are the operating system labels and the values
// are lists of tool labels. // are lists of tool labels.
buildMatrix = [ buildMatrix = [
// Debug builds with ASAN + logging for various OS/compiler combinations. // Debug builds with ASAN + logging for various OS/compiler combinations.
['unix', [ ['Linux', [
builds: ['debug'], builds: ['debug'],
tools: ['gcc4.8', 'gcc4.9', 'gcc5', 'gcc6', 'gcc7', 'gcc8', 'clang'], tools: ['gcc4.8', 'gcc4.9', 'gcc5', 'gcc6', 'gcc7', 'gcc8'],
cmakeArgs: defaultCmakeArgs cmakeArgs: debugBuildFlags,
+ ' -DCAF_LOG_LEVEL:STRING=4' ]],
+ ' -DCAF_ENABLE_ADDRESS_SANITIZER:BOOL=yes', ['macOS', [
]], builds: ['debug'],
// One release build per supported OS. FreeBSD and Windows have the least tools: ['clang'],
// testing outside Jenkins, so we also explicitly schedule debug builds. cmakeArgs: debugBuildFlags,
['Linux', [ ]],
builds: ['release'], // One release build per supported OS. FreeBSD and Windows have the least
tools: ['gcc', 'clang'], // testing outside Jenkins, so we also explicitly schedule debug builds.
cmakeArgs: defaultCmakeArgs, ['Linux', [
]], builds: ['release'],
['macOS', [ tools: ['gcc', 'clang'],
builds: ['release'], cmakeArgs: releaseBuildFlags,
tools: ['clang'], ]],
cmakeArgs: defaultCmakeArgs, ['macOS', [
]], builds: ['release'],
['FreeBSD', [ tools: ['clang'],
builds: ['debug'], // no release build for now, because it takes 1h cmakeArgs: releaseBuildFlags,
tools: ['clang'], ]],
cmakeArgs: defaultCmakeArgs, ['FreeBSD', [
]], builds: ['debug'], // no release build for now, because it takes 1h
['Windows', [ tools: ['clang'],
builds: ['debug', 'release'], cmakeArgs: debugBuildFlags,
tools: ['msvc'], ]],
cmakeArgs: '-DCAF_BUILD_STATIC_ONLY:BOOL=yes' ['Windows', [
+ ' -DCAF_ENABLE_RUNTIME_CHECKS:BOOL=yes' builds: ['debug', 'release'],
+ ' -DCAF_NO_OPENCL:BOOL=yes', tools: ['msvc'],
]], cmakeArgs: [
// One Additional build for coverage reports. 'CAF_BUILD_STATIC_ONLY:BOOL=yes',
['unix', [ 'CAF_ENABLE_RUNTIME_CHECKS:BOOL=yes',
builds: ['debug'], 'CAF_NO_OPENCL:BOOL=yes',
tools: ['gcovr'], ],
extraSteps: ['coverageReport'], ]],
cmakeArgs: '-DCAF_ENABLE_GCOV:BOOL=yes ' // One Additional build for coverage reports.
+ ' -DCAF_NO_EXCEPTIONS:BOOL=yes ' ['Linux', [
+ ' -DCAF_FORCE_NO_EXCEPTIONS:BOOL=yes', builds: ['debug'],
]], tools: ['gcc8 && gcovr'],
extraSteps: ['coverageReport'],
cmakeArgs: [
'CAF_ENABLE_GCOV:BOOL=yes',
'CAF_NO_EXCEPTIONS:BOOL=yes',
'CAF_FORCE_NO_EXCEPTIONS:BOOL=yes',
],
]],
] ]
// Optional environment variables for combinations of labels. // Optional environment variables for combinations of labels.
buildEnvironments = [ buildEnvironments = [
'macOS && gcc': ['CXX=g++'], 'macOS && gcc': ['CXX=g++'],
'Linux && clang': ['CXX=clang++'], 'Linux && clang': ['CXX=clang++'],
] ]
// Called *after* a build succeeded. // Called *after* a build succeeded.
def coverageReport() { def coverageReport() {
dir('caf-sources') { dir('caf-sources') {
sh 'gcovr -e examples -e tools -e libcaf_test -e ".*/test/.*" -e libcaf_core/caf/scheduler/profiled_coordinator.hpp -x -r .. > coverage.xml' sh 'gcovr -e examples -e tools -e libcaf_test -e ".*/test/.*" -e libcaf_core/caf/scheduler/profiled_coordinator.hpp -x -r .. > coverage.xml'
archiveArtifacts '**/coverage.xml' archiveArtifacts '**/coverage.xml'
cobertura([ cobertura([
autoUpdateHealth: false, autoUpdateHealth: false,
autoUpdateStability: false, autoUpdateStability: false,
coberturaReportFile: '**/coverage.xml', coberturaReportFile: '**/coverage.xml',
conditionalCoverageTargets: '70, 0, 0', conditionalCoverageTargets: '70, 0, 0',
failUnhealthy: false, failUnhealthy: false,
failUnstable: false, failUnstable: false,
lineCoverageTargets: '80, 0, 0', lineCoverageTargets: '80, 0, 0',
maxNumberOfBuilds: 0, maxNumberOfBuilds: 0,
methodCoverageTargets: '80, 0, 0', methodCoverageTargets: '80, 0, 0',
onlyStable: false, onlyStable: false,
sourceEncoding: 'ASCII', sourceEncoding: 'ASCII',
zoomCoverageChart: false, zoomCoverageChart: false,
]) ])
} }
} }
def cmakeSteps(buildType, cmakeArgs) { def cmakeSteps(buildType, cmakeArgs, installDir) {
// Configure and build. def absInstallDir = pwd() + '/' + installDir
cmakeBuild([ dir('caf-sources') {
buildDir: 'build', // Configure and build.
buildType: buildType, cmakeBuild([
cmakeArgs: cmakeArgs, buildDir: 'build',
installation: 'cmake in search path', buildType: buildType,
sourceDir: '.', cmakeArgs: "-DCMAKE_INSTALL_PREFIX=\"$absInstallDir\" " + cmakeArgs,
steps: [[withCmake: true]], installation: 'cmake in search path',
]) sourceDir: '.',
// Run unit tests. steps: [[
ctest([ args: '--target install',
arguments: '--output-on-failure', withCmake: true,
installation: 'cmake in search path', ]],
workingDir: 'build', ])
]) // Run unit tests.
ctest([
arguments: '--output-on-failure',
installation: 'cmake in search path',
workingDir: 'build',
])
}
zip([
archive: true,
dir: installDir,
zipFile: "${installDir}.zip",
])
} }
def buildSteps(buildType, cmakeArgs) { // Builds `name` with CMake and runs the unit tests.
echo "build stage: $STAGE_NAME" def buildSteps(buildType, cmakeArgs, installDir) {
deleteDir() echo "build stage: $STAGE_NAME"
unstash('caf-sources') deleteDir()
dir('caf-sources') { dir(installDir) {
// Create directory.
}
unstash('caf-sources')
if (STAGE_NAME.contains('Windows')) { if (STAGE_NAME.contains('Windows')) {
echo "Windows build on $NODE_NAME" echo "Windows build on $NODE_NAME"
withEnv(['PATH=C:\\Windows\\System32;C:\\Program Files\\CMake\\bin;C:\\Program Files\\Git\\cmd;C:\\Program Files\\Git\\bin']) { withEnv(['PATH=C:\\Windows\\System32;C:\\Program Files\\CMake\\bin;C:\\Program Files\\Git\\cmd;C:\\Program Files\\Git\\bin']) {
cmakeSteps(buildType, cmakeArgs) cmakeSteps(buildType, cmakeArgs, installDir)
} }
} else { } else {
echo "Unix build on $NODE_NAME" echo "Unix build on $NODE_NAME"
def leakCheck = STAGE_NAME.contains("Linux") && !STAGE_NAME.contains("clang") def leakCheck = STAGE_NAME.contains("Linux") && !STAGE_NAME.contains("clang")
withEnv(["label_exp=" + STAGE_NAME.toLowerCase(), withEnv(["label_exp=" + STAGE_NAME.toLowerCase(),
"ASAN_OPTIONS=detect_leaks=" + (leakCheck ? 1 : 0)]) { "ASAN_OPTIONS=detect_leaks=" + (leakCheck ? 1 : 0)]) {
cmakeSteps(buildType, cmakeArgs) cmakeSteps(buildType, cmakeArgs, installDir)
} }
} }
} }
// Concatenates CMake flags into a single string.
def makeFlags(xs) {
xs.collect { x -> '-D' + x }.join(' ')
} }
// Builds a stage for given builds. Results in a parallel stage `if builds.size() > 1`. // Builds a stage for given builds. Results in a parallel stage `if builds.size() > 1`.
def makeBuildStages(matrixIndex, builds, lblExpr, settings) { def makeBuildStages(matrixIndex, builds, lblExpr, settings) {
builds.collectEntries { buildType -> builds.collectEntries { buildType ->
def id = "$matrixIndex $lblExpr: $buildType" def id = "$matrixIndex $lblExpr: $buildType"
[ [
(id): (id):
{ {
node(lblExpr) { node(lblExpr) {
stage(id) { stage(id) {
try { try {
withEnv(buildEnvironments[lblExpr] ?: []) { def installDir = "$lblExpr && $buildType"
buildSteps(buildType, settings['cmakeArgs'] ?: '') withEnv(buildEnvironments[lblExpr] ?: []) {
(settings['extraSteps'] ?: []).each { fun -> "$fun"() } buildSteps(buildType, makeFlags(settings['cmakeArgs']), installDir)
} (settings['extraSteps'] ?: []).each { fun -> "$fun"() }
} finally { }
cleanWs() } finally {
cleanWs()
}
}
}
} }
} ]
} }
}
]
}
} }
pipeline { pipeline {
agent none agent none
environment { environment {
LD_LIBRARY_PATH = "$WORKSPACE/caf-sources/build/lib" LD_LIBRARY_PATH = "$WORKSPACE/caf-sources/build/lib"
DYLD_LIBRARY_PATH = "$WORKSPACE/caf-sources/build/lib" DYLD_LIBRARY_PATH = "$WORKSPACE/caf-sources/build/lib"
}
stages {
stage ('Git Checkout') {
agent { label 'master' }
steps {
deleteDir()
dir('caf-sources') {
checkout scm
}
stash includes: 'caf-sources/**', name: 'caf-sources'
}
} }
// Start builds. stages {
stage('Builds') { stage ('Git Checkout') {
steps { agent { label 'master' }
script { steps {
// Create stages for building everything in our build matrix in deleteDir()
// parallel. dir('caf-sources') {
def xs = [:] checkout scm
buildMatrix.eachWithIndex { entry, index -> }
def (os, settings) = entry stash includes: 'caf-sources/**', name: 'caf-sources'
settings['tools'].eachWithIndex { tool, toolIndex -> }
def matrixIndex = "[$index:$toolIndex]" }
def builds = settings['builds'] // Start builds.
def labelExpr = "$os && $tool" stage('Builds') {
xs << makeBuildStages(matrixIndex, builds, labelExpr, settings) steps {
} script {
} // Create stages for building everything in our build matrix in
parallel xs // parallel.
def xs = [:]
buildMatrix.eachWithIndex { entry, index ->
def (os, settings) = entry
settings['tools'].eachWithIndex { tool, toolIndex ->
def matrixIndex = "[$index:$toolIndex]"
def builds = settings['builds']
def labelExpr = "$os && $tool"
xs << makeBuildStages(matrixIndex, builds, labelExpr, settings)
}
}
parallel xs
}
}
} }
}
}
}
post {
success {
emailext(
subject: "✅ CAF build #${env.BUILD_NUMBER} succeeded for job ${env.JOB_NAME}",
recipientProviders: [culprits(), developers(), requestor(), upstreamDevelopers()],
body: "Check console output at ${env.BUILD_URL}.",
)
} }
failure { post {
emailext( success {
subject: "⛔️ CAF build #${env.BUILD_NUMBER} failed for job ${env.JOB_NAME}", emailext(
attachLog: true, subject: "✅ CAF build #${env.BUILD_NUMBER} succeeded for job ${env.JOB_NAME}",
compressLog: true, recipientProviders: [culprits(), developers(), requestor(), upstreamDevelopers()],
recipientProviders: [culprits(), developers(), requestor(), upstreamDevelopers()], body: "Check console output at ${env.BUILD_URL}.",
body: "Check console output at ${env.BUILD_URL} or see attached log.", )
) }
failure {
emailext(
subject: "⛔️ CAF build #${env.BUILD_NUMBER} failed for job ${env.JOB_NAME}",
attachLog: true,
compressLog: true,
recipientProviders: [culprits(), developers(), requestor(), upstreamDevelopers()],
body: "Check console output at ${env.BUILD_URL} or see attached log.",
)
}
} }
}
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment