【问题标题】:How to use Jenkins declarative pipeline to build and test on multiple platforms如何使用 Jenkins 声明式管道在多个平台上构建和测试
【发布时间】:2018-02-20 07:31:25
【问题描述】:

我正在尝试做一些我觉得应该很简单的事情,但我不知道该怎么做。

基本上我有一个 Jenkins 主机(在 Linux 上运行)和两个从机,一个在 Windows 上,另一个在 macOS 上。

我想在所有 3 个平台上构建我的项目并在所有 3 个平台上运行 GTest 测试。

我可以构建并运行测试,但 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 块放在 node 块中的 parallel 步骤中的测试阶段,但它似乎没有做任何事情 - 它甚至没有出现在控制台中输出。

这是我的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'
                                }
                            }
                        }
                    }
                )
            }
        }
    }

}

我做错了什么?

【问题讨论】:

  • 只是一些一般性建议:让它更小。放置平台,除了一个放置阶段,将一切都放在一个步骤中 - 做任何必要的事情来真正看到它工作。然后,重新添加原始管道的东西;希望你能准确地看到它发生故障的地方。
  • 当你有多个节点并且并行时,不要在后期构建步骤中记录。执行构建命令后,在每个节点中将测试报告作为一个步骤发布。参考:github.com/jenkins-infra/pipeline-library/blob/master/vars/…

标签: jenkins cmake jenkins-pipeline googletest jenkins-declarative-pipeline


【解决方案1】:
  1. post{} 块只能跟随steps{}parallel{}(用于并行阶段)才能生效。

  2. 如果你需要在节点环境下执行post,你应该为整个stage提供一个节点(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.)
    }
}

您也可以在帖子声明中使用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
                )
            }
        }
    }
}

【讨论】:

    猜你喜欢
    • 2019-01-02
    • 2017-12-03
    • 1970-01-01
    • 1970-01-01
    • 2017-08-12
    • 2021-01-15
    • 2018-05-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多