I'm trying to do something that I feel should be simple to do, but I can't figure out how.
Basically I have a Jenkins master (running on Linux) and two slaves, one on Windows and the other on macOS.
I want to build my project on all 3 platforms and run GTest tests on all 3 platforms too.
I can build and run the test, but the junit step doesn't seem to collect any test results.
I tried to put the post
block everywhere, but it just doesn't work. If I try to put the post
block in the Test stage or as a sibling of stages
, I get the following error:
Required context class hudson.FilePath is missing
Perhaps you forgot to surround the code with a step that provides this, such as: node
which is caused by agent none
- the post
block doesn't know where to run.
So I tried to put the post
block inside the node
block in my parallel
step for the Test stage, but it doesn't seem to do anything - it doesn't even show up in the console output.
Here's my Jenkinsfile
:
pipeline {
agent none
stages {
stage ('Clean') {
steps {
parallel (
"linux" : {
node ("linux") {
dir("build") {
deleteDir()
writeFile file:'dummy', text:'' // Creates the directory
}
}
},
"windows" : {
node('windows') {
dir("build") {
deleteDir()
writeFile file:'dummy', text:'' // Creates the directory
}
}
},
"mac" : {
node('mac') {
dir("build") {
deleteDir()
writeFile file:'dummy', text:'' // Creates the directory
}
}
}
)
}
}
stage ('Build') {
steps {
parallel (
"linux" : {
node ("linux") {
checkout scm
dir("build") {
sh '/opt/cmake/bin/cmake .. -DCMAKE_BUILD_TYPE=Release'
sh 'make'
}
}
},
"windows" : {
node('windows') {
checkout(changelog: false, scm: scm) // Changelog to false, otherwise Jenkins shows duplicates. Only linux (the Jenkins master) has the changelog enabled.
dir("build") {
bat 'cmake .. -G "Visual Studio 15 2017 Win64" -DCMAKE_PREFIX_PATH=C:/Qt/5.9.1/msvc2017_64'
bat "\"${tool 'MSBuild'}\" project.sln /p:Configuration=Release /p:Platform=\"x64\" /p:ProductVersion=1.0.0.${env.BUILD_NUMBER} /m"
}
}
},
"mac" : {
node('mac') {
checkout(changelog: false, scm: scm) // Changelog to false, otherwise Jenkins shows duplicates. Only linux (the Jenkins master) has the changelog enabled.
dir("build") {
sh 'cmake .. -DCMAKE_PREFIX_PATH=/usr/local/Cellar/qt/5.9.1 -DCMAKE_BUILD_TYPE=Release'
sh 'make'
}
}
}
)
}
}
stage ('Test') {
steps {
parallel (
"linux" : {
node ("linux") {
dir('Build') {
sh './bin/project-tests --gtest_output=xml:project-tests-results.xml'
// Add other test executables here.
}
post {
always {
junit '*-tests-results.xml'
}
}
}
},
"windows" : {
node('windows') {
dir("build") {
bat 'tests\\project\\Release\\project-tests --gtest_output=xml:project-tests-results.xml'
// Add other test executables here.
}
post {
always {
junit '*-tests-results.xml'
}
}
}
},
"mac" : {
node('mac') {
dir("build") {
sh './bin/project-tests --gtest_output=xml:project-tests-results.xml'
// Add other test executables here.
}
post {
always {
junit '*-tests-results.xml'
}
}
}
}
)
}
}
}
}
What am I doing wrong?
Step 1− If multi node selection was enabled, you get the chance to select multiple nodes to run the job on. The job will then be executed on each of the nodes, one after the other or concurrent - depending on the configuration.
Different Types of Jenkins CI/CD Pipelines. Scripted Pipeline. Declarative Pipeline.
Jenkins Pipeline allows you to compose multiple steps in an easy way that can help you model any sort of automation process. Think of a "step" like a single command which performs a single action.
post{}
block should only follow steps{}
or parallel{}
(for parallel stages) to take effect.
If you require post to be executed in a node environment, you should provide a node to the entire stage (agent{}
statement).
You could try to use parallel stages execution. Also I'd suggest to use functions to shorten the code.
Something like this:
void Clean() {
dir("build") {
deleteDir()
writeFile file:'dummy', text:'' // Creates the directory
}
}
void SmthElse(def optionalParams) {
// some actions here
}
pipeline {
agent none
options {
skipDefaultCheckout(true) // to avoid force checkouts on every node in a first stage
disableConcurrentBuilds() // to avoid concurrent builds on same nodes
}
stages {
stage('Clean') {
failfast false
parallel {
stage('Linux') {
agent {label 'linux'}
steps {Clean()}
post {
// post statements for 'linux' node
SmthElse(someParameter)
}
}
stage('Windows') {
agent {label 'windows'}
steps {Clean()}
post {
// post statements for 'windows' node
}
}
stage('MacOS') {
agent {label 'mac'}
steps {Clean()}
post {
// post statements for 'mac' node
}
}
}
post {
// Post statements OUTSIDE of nodes (i.e. send e-mail of a stage completion)
}
}
// other stages (Build/Test/Etc.)
}
}
Alternatively you can use node
in post statements:
stage('Test') {
steps {
// your parallel Test steps
}
post {
always {
script {
parallel (
"linux" : {
node('linux') {
// 'linux' node post steps
}
},
"windows" : {
node('windows') {
// 'windows' node post steps
}
}
// etc
)
}
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With