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
40e7b16e
Commit
40e7b16e
authored
Jun 13, 2019
by
Dominik Charousset
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'topic/jenkins'
parents
114dfc65
c604b272
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
111 additions
and
320 deletions
+111
-320
Jenkinsfile
Jenkinsfile
+111
-320
No files found.
Jenkinsfile
View file @
40e7b16e
#
!
/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,340 +15,130 @@ defaultDebugBuildFlags = defaultReleaseBuildFlags + [
...
@@ -13,340 +15,130 @@ 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'
,
'release'
],
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/caf-test'
,
],
relativeExcludePaths:
[
release:
defaultReleaseBuildFlags
+
[
'examples'
,
'CAF_BUILD_STATIC_ONLY:BOOL=yes'
,
'tools'
,
'libcaf_test'
,
'libcaf_core/test'
,
'libcaf_io/test'
,
'libcaf_openssl/test'
,
'libcaf_opencl'
,
'libcaf_core/caf/scheduler/profiled_coordinator.hpp'
,
],
],
],
],
]
]
// 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
()
getSources
(
config
)
dir
(
'caf-sources'
)
{
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
(
'Documentation'
)
{
agent
{
label
'pandoc'
}
agent
{
label
'pandoc'
}
steps
{
steps
{
deleteDir
()
deleteDir
()
unstash
(
'
caf-
sources'
)
unstash
(
'sources'
)
dir
(
'
caf-
sources'
)
{
dir
(
'sources'
)
{
// Configure and build.
// Configure and build.
cmakeBuild
([
cmakeBuild
([
buildDir:
'build'
,
buildDir:
'build'
,
...
@@ -374,14 +166,14 @@ pipeline {
...
@@ -374,14 +166,14 @@ pipeline {
])
])
sh
"""
sh
"""
if [ "${env.GIT_BRANCH}" = "master" ]; then
if [ "${env.GIT_BRANCH}" = "master" ]; then
cp ../
caf-
sources/build/doc/rst/* .
cp ../sources/build/doc/rst/* .
if [ -n "\$(git status --porcelain)" ]; then
if [ -n "\$(git status --porcelain)" ]; then
git add .
git add .
git commit -m "Update Manual"
git commit -m "Update Manual"
git push --set-upstream origin master
git push --set-upstream origin master
if [ -z "\$(grep 'exp.sha' ../
caf-
sources/release.txt)" ] ; then
if [ -z "\$(grep 'exp.sha' ../sources/release.txt)" ] ; then
git tag \$(cat ../
caf-
sources/release.txt)
git tag \$(cat ../sources/release.txt)
git push origin \$(cat ../
caf-
sources/release.txt)
git push origin \$(cat ../sources/release.txt)
fi
fi
fi
fi
fi
fi
...
@@ -389,23 +181,22 @@ pipeline {
...
@@ -389,23 +181,22 @@ pipeline {
}
}
}
}
}
}
stage
(
'Notify'
)
{
steps
{
collectResults
(
config
,
PrettyJobName
)
}
}
}
}
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