繁体   English   中英

在多个工作中重复使用jenkins管道的各个阶段

[英]Reusing stages of a jenkins pipeline in multiple jobs

我的团队正在转向Jenkins 2,我正在使用管道插件,以便我们的构建可以存在于我们的存储库中。 因为在我们公司中获得分配的存储库有很多开销,所以我们有一个存储库,其中包含许多子项目和子模块。

我想要的是为每个子模块单独构建和报告Junit / checkstyle / etc报告,以及每个子项目的最终“构建和部署”步骤。

我目前的计划是为每个子模块创建单独的作业,以便他们获得自己的junit / checkstyle / etc报告页面。 然后有一个多作业项目来为子项目编排子模块构建。 由于所有子项目都是简单的jar构建,我想将大量逻辑放在一个公共文件中,让我们在子项目的根目录中调用它为JenkinsfileForJars。 回购结构是

  • 子项目
    • JenkinsfileForJars.groovy
    • 子moduleA
      • Jenkinsfile
    • 子moduleB
      • Jenkinsfile

我的Jenkinsfile包含

def submoduleName = "submoduleA"
def pipeline
node {

    pipeline = load("${env.WORKSPACE}/subproject/JenkinsfileForJars.groovy")

}
pipeline.build()
pipeline.results()

我的JenkinsfileForJars包含

def build() {

    stage('Build') {
        // Run the maven build
        dir("subproject") {
            sh "./gradlew ${submoduleName}:build"
        }

    }
}
def results() {

    stage('Results') {
        dir("subproject/${submoduleName}") {
            junit 'build/test-results/TEST-*.xml'
            archive 'build/libs/*.jar'
            publishHTML([allowMissing: false, alwaysLinkToLastBuild: false, keepAll: false, reportDir: 'build/reports/cobertura/', reportFiles: 'frame-summary.html', reportName: 'Cobertura Report'])
            publishHTML([allowMissing: false, alwaysLinkToLastBuild: false, keepAll: false, reportDir: 'build/reports/findbugs/', reportFiles: 'main.html', reportName: 'Fidbugs Report'])
            publishHTML([allowMissing: false, alwaysLinkToLastBuild: false, keepAll: false, reportDir: 'build/reports/pmd/', reportFiles: 'main.html', reportName: 'PMD Report'])
            step([$class: 'CheckStylePublisher', pattern: 'build/reports/checkstyle/main.xml', unstableTotalAll: '200', usePreviousBuildAsReference: true])
        }
    }

}

return this;

当我运行上面的Jenkinsfile时,我收到以下错误:

Running on master in /var/lib/jenkins/workspace/jobA
[Pipeline] {
[Pipeline] load
[Pipeline] { (/var/lib/jenkins/workspace/jobA/subproject/JenkinsfileForJars.groovy)
[Pipeline] }
[Pipeline] // load
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
java.lang.NullPointerException: Cannot invoke method build() on null object

据我所知,我正在关注加载手动脚本的文档中显示的内容以及为加载的脚本提供示例 我不明白为什么我的脚本在load命令后为null。

如何让我的Jenkinsfile加载JenkinsfileForJars.groovy?

问题与Blake Mitchell在上述评论中提到的SCM结账有关。 由于您正在从子模块加载groovy函数,因此如果您只想在主服务器上保留裸存储库,则需要首先检出子模块,最好是在构建代理/从服务器上。

def pipeline
node( 'myAgentLabel' ) {
    stage ( 'checkout SCM' ) {
        checkout([
            $class: 'GitSCM'
            ,branches: scm.branches
            ,extensions: scm.extensions 
                + [[ $class: 'SubmoduleOption', disableSubmodules: false, parentCredentials: true, recursiveSubmodules: true, reference: '', trackingSubmodules: false]]
            ,doGenerateSubmoduleConfigurations: false
            ,userRemoteConfigs: scm.userRemoteConfigs
        ])
        pipeline = load( "${env.WORKSPACE}/path/to/submodule/myGroovyFunctions.grooovy" )
    }
    pipeline.build()
}

请注意,在结帐示例中,访问scm。*属性也需要由Jenkins中的管理员列入白名单(进程内脚本批准)

可能存在两个可能的问题:

  • 为什么要将负载放在节点结构中。 此导入不需要计算资源,因此您不需要它。
  • 对构建的调用应放在节点结构中。 并且可能对结果的调用也应该在(相同的)节点结构内,以确保归档正确的结果(如果使用多个(从属)节点)。

(这应该是你问题下方的评论,但我没有足够的积分在那里添加评论。)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM