如何使用 Jenkins 声明式管道在多个平台上构建和测试
How to use Jenkins declarative pipeline to build and test on multiple platforms
我想做一些我觉得应该很容易做的事情,但我不知道怎么做。
基本上我有一个 Jenkins master(运行ning on Linux)和两个 slave,一个在 Windows 上,另一个在 macOS 上。
我想在所有 3 个平台上构建我的项目,运行 GTest 也在所有 3 个平台上测试。
我可以构建和 运行 测试,但 junit 步骤似乎没有收集任何测试结果。
我试着把 post
块放在任何地方,但它不起作用。如果我尝试将 post
块放在测试阶段或作为 stages
的同级块,我会收到以下错误:
Required context class hudson.FilePath is missing
Perhaps you forgot to surround the code with a step that provides this, such as: node
这是由 agent none
引起的 - post
块不知道 运行.
的位置
所以我尝试将 post
块放在 parallel
测试阶段步骤中的 node
块内,但它似乎没有做任何事情 - 它没有'甚至出现在控制台输出中。
这是我的 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'
}
}
}
}
)
}
}
}
}
我做错了什么?
post{}
块应仅在 steps{}
或 parallel{}
(对于并行阶段)之后生效。
如果需要post在node环境下执行,需要给整个stage提供一个node(agent{}
语句)
您可以尝试使用并行阶段执行。另外我建议使用函数来缩短代码。
像这样:
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.)
}
}
或者,您可以在 post 语句中使用 node
:
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
)
}
}
}
}
我想做一些我觉得应该很容易做的事情,但我不知道怎么做。
基本上我有一个 Jenkins master(运行ning on Linux)和两个 slave,一个在 Windows 上,另一个在 macOS 上。
我想在所有 3 个平台上构建我的项目,运行 GTest 也在所有 3 个平台上测试。
我可以构建和 运行 测试,但 junit 步骤似乎没有收集任何测试结果。
我试着把 post
块放在任何地方,但它不起作用。如果我尝试将 post
块放在测试阶段或作为 stages
的同级块,我会收到以下错误:
Required context class hudson.FilePath is missing
Perhaps you forgot to surround the code with a step that provides this, such as: node
这是由 agent none
引起的 - post
块不知道 运行.
所以我尝试将 post
块放在 parallel
测试阶段步骤中的 node
块内,但它似乎没有做任何事情 - 它没有'甚至出现在控制台输出中。
这是我的 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'
}
}
}
}
)
}
}
}
}
我做错了什么?
post{}
块应仅在steps{}
或parallel{}
(对于并行阶段)之后生效。如果需要post在node环境下执行,需要给整个stage提供一个node(
agent{}
语句)
您可以尝试使用并行阶段执行。另外我建议使用函数来缩短代码。
像这样:
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.)
}
}
或者,您可以在 post 语句中使用 node
:
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
)
}
}
}
}