Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
A
Actor Framework
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
cpp-libs
Actor Framework
Commits
72962540
Commit
72962540
authored
Jun 12, 2019
by
Dominik Charousset
Committed by
Dominik Charousset
Jun 12, 2019
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Switch to new shared Jenkins library
parent
114dfc65
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
96 additions
and
359 deletions
+96
-359
Jenkinsfile
Jenkinsfile
+96
-359
No files found.
Jenkinsfile
View file @
72962540
#
!
/usr/
bin
/
env
groovy
#
!
/usr/
bin
/
env
groovy
@Library
(
'caf-continuous-integration'
)
_
// Default CMake flags for release builds.
// Default CMake flags for release builds.
defaultReleaseBuildFlags
=
[
defaultReleaseBuildFlags
=
[
'CAF_ENABLE_RUNTIME_CHECKS:BOOL=yes'
,
'CAF_ENABLE_RUNTIME_CHECKS:BOOL=yes'
,
...
@@ -13,399 +15,134 @@ defaultDebugBuildFlags = defaultReleaseBuildFlags + [
...
@@ -13,399 +15,134 @@ defaultDebugBuildFlags = defaultReleaseBuildFlags + [
'CAF_LOG_LEVEL:STRING=TRACE'
,
'CAF_LOG_LEVEL:STRING=TRACE'
,
]
]
defaultBuildFlags
=
[
// Configures the behavior of our stages.
debug:
defaultDebugBuildFlags
,
config
=
[
release:
defaultReleaseBuildFlags
,
// GitHub path to repository.
]
repository:
'actor-framework/actor-framework'
,
// List of enabled checks for email notifications.
// CMake flags by OS and build type.
checks:
[
buildFlags
=
[
'build'
,
macOS:
[
'style'
,
debug:
defaultDebugBuildFlags
+
[
'tests'
,
'OPENSSL_ROOT_DIR=/usr/local/opt/openssl'
,
'coverage'
,
'OPENSSL_INCLUDE_DIR=/usr/local/opt/openssl/include'
,
],
// Our build matrix. Keys are the operating system labels and values are build configurations.
buildMatrix:
[
[
'Linux'
,
[
builds:
[
'debug'
],
tools:
[
'gcc4.8'
,
'gcc4.9'
,
'gcc5'
,
'gcc6'
,
'gcc7'
],
]],
[
'Linux'
,
[
builds:
[
'debug'
],
tools:
[
'gcc8'
],
extraSteps:
[
'coverageReport'
],
]],
[
'Linux'
,
[
builds:
[
'release'
],
tools:
[
'gcc8'
,
'clang'
],
]],
[
'macOS'
,
[
builds:
[
'debug'
,
'release'
],
tools:
[
'clang'
],
]],
[
'FreeBSD'
,
[
builds:
[
'debug'
],
// no release build for now, because it takes 1h
tools:
[
'clang'
],
]],
[
'Windows'
,
[
// TODO: debug build currently broken
//builds: ['debug', 'release'],
builds:
[
'release'
],
tools:
[
'msvc'
],
]],
],
// Platform-specific environment settings.
buildEnvironments:
[
nop:
[],
// Dummy value for getting the proper types.
],
// Default CMake flags by build type.
defaultBuildFlags:
[
debug:
defaultDebugBuildFlags
,
release:
defaultReleaseBuildFlags
,
],
// CMake flags by OS and build type to override defaults for individual builds.
buildFlags:
[
macOS:
[
debug:
defaultDebugBuildFlags
+
[
'OPENSSL_ROOT_DIR=/usr/local/opt/openssl'
,
'OPENSSL_INCLUDE_DIR=/usr/local/opt/openssl/include'
,
],
release:
defaultReleaseBuildFlags
+
[
'OPENSSL_ROOT_DIR=/usr/local/opt/openssl'
,
'OPENSSL_INCLUDE_DIR=/usr/local/opt/openssl/include'
,
],
],
],
release:
defaultReleaseBuildFlags
+
[
Windows:
[
'OPENSSL_ROOT_DIR=/usr/local/opt/openssl'
,
debug:
defaultDebugBuildFlags
+
[
'OPENSSL_INCLUDE_DIR=/usr/local/opt/openssl/include'
,
'CAF_BUILD_STATIC_ONLY:BOOL=yes'
,
],
release:
defaultReleaseBuildFlags
+
[
'CAF_BUILD_STATIC_ONLY:BOOL=yes'
,
],
],
],
],
],
Windows:
[
// Configures what binary the coverage report uses and what paths to exclude.
debug:
defaultDebugBuildFlags
+
[
coverage:
[
'CAF_BUILD_STATIC_ONLY:BOOL=yes'
,
binary:
'build/bin/caf-test'
,
],
relativeExcludePaths:
[
release:
defaultReleaseBuildFlags
+
[
'test'
,
'CAF_BUILD_STATIC_ONLY:BOOL=yes'
,
],
],
],
],
]
]
// Our build matrix. The keys are the operating system labels and the values
// Declarative pipeline for triggering all stages.
// are lists of tool labels.
buildMatrix
=
[
[
'Linux'
,
[
builds:
[
'debug'
],
tools:
[
'gcc4.8'
,
'gcc4.9'
,
'gcc5'
,
'gcc6'
,
'gcc7'
],
]],
[
'Linux'
,
[
builds:
[
'debug'
],
tools:
[
'gcc8'
],
extraSteps:
[
'coverageReport'
],
]],
[
'Linux'
,
[
builds:
[
'release'
],
tools:
[
'gcc8'
,
'clang'
],
]],
[
'macOS'
,
[
builds:
[
'debug'
,
'release'
],
tools:
[
'clang'
],
]],
[
'FreeBSD'
,
[
builds:
[
'debug'
],
// no release build for now, because it takes 1h
tools:
[
'clang'
],
]],
[
'Windows'
,
[
// TODO: debug build currently broken
//builds: ['debug', 'release'],
builds:
[
'release'
],
tools:
[
'msvc'
],
]],
]
// Optional environment variables for combinations of labels.
buildEnvironments
=
[
'macOS && gcc'
:
[
'CXX=g++'
],
'Linux && clang'
:
[
'CXX=clang++'
],
]
// Adds additional context information to commits on GitHub.
def
setBuildStatus
(
context
,
state
,
message
)
{
echo
"set ${context} result for commit ${env.GIT_COMMIT} to $state: $message"
step
([
$class
:
'GitHubCommitStatusSetter'
,
commitShaSource:
[
$class
:
'ManuallyEnteredShaSource'
,
sha:
env
.
GIT_COMMIT
,
],
reposSource:
[
$class
:
'ManuallyEnteredRepositorySource'
,
url:
env
.
GIT_URL
,
],
contextSource:
[
$class
:
'ManuallyEnteredCommitContextSource'
,
context:
context
,
],
errorHandlers:
[[
$class
:
'ChangingBuildStatusErrorHandler'
,
result:
'SUCCESS'
,
]],
statusResultSource:
[
$class
:
'ConditionalStatusResultSource'
,
results:
[[
$class
:
'AnyBuildResult'
,
state:
state
,
message:
message
,
]]
],
]);
}
// Creates coverage reports via the Cobertura plugin.
def
coverageReport
(
buildId
)
{
echo
"Create coverage report for build ID $buildId"
// Paths we wish to ignore in the coverage report.
def
installDir
=
"$WORKSPACE/$buildId"
def
excludePaths
=
[
"/usr/"
,
"$WORKSPACE/caf-sources/examples"
,
"$WORKSPACE/caf-sources/tools"
,
"$WORKSPACE/caf-sources/libcaf_test"
,
"$WORKSPACE/caf-sources/libcaf_core/test"
,
"$WORKSPACE/caf-sources/libcaf_io/test"
,
"$WORKSPACE/caf-sources/libcaf_openssl/test"
,
"$WORKSPACE/caf-sources/libcaf_opencl"
,
"$WORKSPACE/caf-sources/libcaf_core/caf/scheduler/profiled_coordinator.hpp"
,
]
def
excludePathsStr
=
excludePaths
.
join
(
','
)
dir
(
'caf-sources'
)
{
try
{
withEnv
([
'ASAN_OPTIONS=verify_asan_link_order=false:detect_leaks=0'
])
{
sh
"""
kcov --exclude-path=$excludePathsStr kcov-result ./build/caf-test &> kcov_output.txt
find . -name 'coverage.json' -exec mv {} result.json \\;
"""
}
stash
includes:
'result.json'
,
name:
'coverage-result'
archiveArtifacts
'**/cobertura.xml'
cobertura
([
autoUpdateHealth:
false
,
autoUpdateStability:
false
,
coberturaReportFile:
'**/cobertura.xml'
,
conditionalCoverageTargets:
'70, 0, 0'
,
failUnhealthy:
false
,
failUnstable:
false
,
lineCoverageTargets:
'80, 0, 0'
,
maxNumberOfBuilds:
0
,
methodCoverageTargets:
'80, 0, 0'
,
onlyStable:
false
,
sourceEncoding:
'ASCII'
,
zoomCoverageChart:
false
,
])
}
catch
(
Exception
e
)
{
echo
"exception: $e"
archiveArtifacts
'kcov_output.txt'
}
}
}
// Wraps `cmakeBuild`.
def
cmakeSteps
(
buildType
,
cmakeArgs
,
buildId
)
{
def
installDir
=
"$WORKSPACE/$buildId"
dir
(
'caf-sources'
)
{
// Configure and build.
cmakeBuild
([
buildDir:
'build'
,
buildType:
buildType
,
cmakeArgs:
(
cmakeArgs
+
[
"CMAKE_INSTALL_PREFIX=\"$installDir\""
,
]).
collect
{
x
->
'-D'
+
x
}.
join
(
' '
),
installation:
'cmake in search path'
,
sourceDir:
'.'
,
steps:
[[
args:
'--target install'
,
withCmake:
true
,
]],
])
// Run unit tests.
try
{
ctest
([
arguments:
'--output-on-failure'
,
installation:
'cmake in search path'
,
workingDir:
'build'
,
])
writeFile
file:
"${buildId}.success"
,
text:
"success\n"
}
catch
(
Exception
)
{
writeFile
file:
"${buildId}.failure"
,
text:
"failure\n"
}
stash
includes:
"${buildId}.*"
,
name:
buildId
}
// Only generate artifacts for the master branch.
if
(
PrettyJobBaseName
==
'master'
)
{
zip
([
archive:
true
,
dir:
buildId
,
zipFile:
"${buildId}.zip"
,
])
}
}
// Builds `name` with CMake and runs the unit tests.
def
buildSteps
(
buildType
,
cmakeArgs
,
buildId
)
{
echo
"build stage: $STAGE_NAME"
deleteDir
()
dir
(
buildId
)
{
// Create directory.
}
unstash
(
'caf-sources'
)
if
(
STAGE_NAME
.
contains
(
'Windows'
))
{
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'
])
{
cmakeSteps
(
buildType
,
cmakeArgs
,
buildId
)
}
}
else
{
echo
"Unix build on $NODE_NAME"
withEnv
([
"label_exp="
+
STAGE_NAME
.
toLowerCase
(),
"ASAN_OPTIONS=detect_leaks=0"
])
{
cmakeSteps
(
buildType
,
cmakeArgs
,
buildId
)
}
}
}
// Builds a stage for given builds. Results in a parallel stage `if builds.size() > 1`.
def
makeBuildStages
(
matrixIndex
,
os
,
builds
,
lblExpr
,
settings
)
{
builds
.
collectEntries
{
buildType
->
def
id
=
"$matrixIndex $lblExpr: $buildType"
[
(
id
):
{
node
(
lblExpr
)
{
stage
(
id
)
{
try
{
def
buildId
=
"${lblExpr}_${buildType}"
.
replace
(
' && '
,
'_'
)
withEnv
(
buildEnvironments
[
lblExpr
]
?:
[])
{
buildSteps
(
buildType
,
(
buildFlags
[
os
]
?:
defaultBuildFlags
)[
buildType
],
buildId
)
(
settings
[
'extraSteps'
]
?:
[]).
each
{
fun
->
"$fun"
(
buildId
)
}
}
}
finally
{
cleanWs
()
}
}
}
}
]
}
}
pipeline
{
pipeline
{
options
{
options
{
buildDiscarder
(
logRotator
(
numToKeepStr:
'20'
,
artifactNumToKeepStr:
'5'
))
// Store no more than 50 logs and 10 artifacts.
buildDiscarder
(
logRotator
(
numToKeepStr:
'50'
,
artifactNumToKeepStr:
'3'
))
}
agent
{
label
'master'
}
}
agent
none
environment
{
environment
{
LD_LIBRARY_PATH
=
"$WORKSPACE/caf-sources/build/lib"
DYLD_LIBRARY_PATH
=
"$WORKSPACE/caf-sources/build/lib"
PrettyJobBaseName
=
env
.
JOB_BASE_NAME
.
replace
(
'%2F'
,
'/'
)
PrettyJobBaseName
=
env
.
JOB_BASE_NAME
.
replace
(
'%2F'
,
'/'
)
PrettyJobName
=
"CAF build #${env.BUILD_NUMBER} for $PrettyJobBaseName"
PrettyJobName
=
"CAF/$PrettyJobBaseName #${env.BUILD_NUMBER}"
ASAN_OPTIONS
=
'detect_leaks=0'
}
}
stages
{
stages
{
stage
(
'Git Checkout'
)
{
stage
(
'Checkout'
)
{
agent
{
label
'master'
}
steps
{
steps
{
deleteDir
()
notifyAllChecks
(
config
,
'pending'
,
''
)
dir
(
'caf-sources'
)
{
getSources
(
config
)
checkout
scm
sh
'./scripts/get-release-version.sh'
/// We really don't need to copy the .git folder around.
dir
(
'.git'
)
{
deleteDir
()
}
}
zip
([
archive:
true
,
dir:
'caf-sources'
,
zipFile:
'sources.zip'
,
])
stash
includes:
'caf-sources/**'
,
name:
'caf-sources'
}
}
}
}
stage
(
'Builds'
)
{
stage
(
'Lint'
)
{
agent
{
label
'clang-format'
}
steps
{
steps
{
script
{
runClangFormat
(
config
)
// Create stages for building everything in our build matrix in
// 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
,
os
,
builds
,
labelExpr
,
settings
)
}
}
parallel
xs
}
}
}
}
}
stage
(
'Check Test Results'
)
{
stage
(
'Build'
)
{
agent
{
label
'master'
}
steps
{
steps
{
script
{
buildParallel
(
config
,
PrettyJobBaseName
)
dir
(
'tmp'
)
{
// Compute the list of all build IDs.
def
buildIds
=
[]
buildMatrix
.
each
{
entry
->
def
(
os
,
settings
)
=
entry
settings
[
'tools'
].
each
{
tool
->
settings
[
'builds'
].
each
{
buildIds
<<
"${os}_${tool}_${it}"
}
}
}
// Compute how many tests have succeeded
def
builds
=
buildIds
.
size
()
def
successes
=
buildIds
.
inject
(
0
)
{
result
,
buildId
->
try
{
unstash
buildId
}
catch
(
Exception
)
{
}
result
+
(
fileExists
(
"${buildId}.success"
)
?
1
:
0
)
}
echo
"$successes unit tests tests of $builds were successful"
if
(
builds
==
successes
)
{
setBuildStatus
(
'unit-tests'
,
'SUCCESS'
,
'All builds passed the unit tests'
)
}
else
{
def
failures
=
builds
-
successes
setBuildStatus
(
'unit-tests'
,
'FAILURE'
,
"$failures/$builds builds failed to run the unit tests"
)
}
// Get the coverage result.
try
{
unstash
'coverage-result'
if
(
fileExists
(
'result.json'
))
{
def
resultJson
=
readJSON
file:
'result.json'
setBuildStatus
(
'coverage'
,
'SUCCESS'
,
resultJson
[
'percent_covered'
]
+
'% coverage'
)
}
else
{
setBuildStatus
(
'coverage'
,
'FAILURE'
,
'Unable to get coverage report'
)
}
}
catch
(
Exception
)
{
setBuildStatus
(
'coverage'
,
'FAILURE'
,
'Unable to generate coverage report'
)
}
}
}
}
}
}
}
stage
(
'Documentation'
)
{
stage
(
'Notify'
)
{
agent
{
label
'pandoc'
}
steps
{
steps
{
deleteDir
()
collectResults
(
config
,
PrettyJobName
)
unstash
(
'caf-sources'
)
dir
(
'caf-sources'
)
{
// Configure and build.
cmakeBuild
([
buildDir:
'build'
,
installation:
'cmake in search path'
,
sourceDir:
'.'
,
cmakeArgs:
'-DCAF_BUILD_TEX_MANUAL=yes'
,
steps:
[[
args:
'--target doc'
,
withCmake:
true
,
]],
])
sshagent
([
'84d71a75-cbb6-489a-8f4c-d0e2793201e9'
])
{
sh
"""
if [ "${env.GIT_BRANCH}" = "master" ]; then
rsync -e "ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null" -r -z --delete build/doc/html/ www.inet.haw-hamburg.de:/users/www/www.actor-framework.org/html/doc
scp -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null build/doc/manual.pdf www.inet.haw-hamburg.de:/users/www/www.actor-framework.org/html/pdf/manual.pdf
fi
"""
}
}
dir
(
'read-the-docs'
)
{
git
([
credentialsId:
'9b054212-9bb4-41fd-ad8e-b7d47495303f'
,
url:
'git@github.com:actor-framework/read-the-docs.git'
,
])
sh
"""
if [ "${env.GIT_BRANCH}" = "master" ]; then
cp ../caf-sources/build/doc/rst/* .
if [ -n "\$(git status --porcelain)" ]; then
git add .
git commit -m "Update Manual"
git push --set-upstream origin master
if [ -z "\$(grep 'exp.sha' ../caf-sources/release.txt)" ] ; then
git tag \$(cat ../caf-sources/release.txt)
git push origin \$(cat ../caf-sources/release.txt)
fi
fi
fi
"""
}
}
}
}
}
}
}
post
{
post
{
success
{
emailext
(
subject:
"✅ $PrettyJobName succeeded"
,
recipientProviders:
[
culprits
(),
developers
(),
requestor
(),
upstreamDevelopers
()],
body:
"Check console output at ${env.BUILD_URL}."
,
)
}
failure
{
failure
{
emailext
(
emailext
(
subject:
"⛔️ $PrettyJobName failed"
,
subject:
"$PrettyJobName: "
+
config
[
'checks'
].
collect
{
"⛔️ ${it}"
}.
join
(
', '
),
recipientProviders:
[
culprits
(),
developers
(),
requestor
(),
upstreamDevelopers
()],
attachLog:
true
,
attachLog:
true
,
compressLog:
true
,
compressLog:
true
,
recipientProviders:
[
culprits
(),
developers
(),
requestor
(),
upstreamDevelopers
()],
body:
"Check console output at ${env.BUILD_URL} or see attached log.\n"
,
body:
"Check console output at ${env.BUILD_URL} or see attached log.\n"
,
)
)
notifyAllChecks
(
config
,
'failure'
,
'Failed due to earlier error'
)
}
}
}
}
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment