Return 来自 Groovy Jenkins DSL 管道中 bat 函数的值

Return value from bat function in Groovy DSL Pipeline in Jenkins

背景

我在 Jenkins 中编写了一个 Groovy DSL 声明管道脚本。该脚本在 Windows Server 2012 上运行的从属代理上执行。在此代理机器上有一个名为 kitchen 的命令行可执行文件。我使用 Groovy 的 bat() 方法执行 kitchen 程序,并传入一个在构建时传递到管道中的参数。

脚本很简单,分两个阶段执行以下操作

  1. 接收一个 AWARD_YEAR 参数
  2. 从 SVN 检出一个项目
  3. 通过bat()函数执行kitchen程序

我正在使用 Jenkins 2.235.3

问题

kitchen 可执行文件 returns 退出代码在 0 - 9 范围内。当退出代码不是 0 时,表示可执行文件失败。然而,就目前而言,不管退出代码如何,管道执行总是成功的。要解决这个问题,我需要将退出代码存储在一个变量中,然后检查它的值。

但是,当我尝试将结果存储到变量中时,出现如下所示的错误。

代码和错误

Below is the code that causes the error

pipeline {
    agent { label 'pentaho-test' }


    parameters {
        string(name: 'AWARD_YEAR', defaultValue: "${Calendar.getInstance().get(Calendar.YEAR)}", description: 'Award Year Parameter')
    }
    
    stages {
        stage('Checkout') {
            steps {
                checkout changelog: false, poll: false, scm: [
                        $class: 'SubversionSCM', 
                        additionalCredentials: [], 
                        excludedCommitMessages: '', 
                        excludedRegions: '', 
                        excludedRevprop: '', 
                        excludedUsers: '', 
                        filterChangelog: false, 
                        ignoreDirPropChanges: false, 
                        includedRegions: '', 
                        locations: [[cancelProcessOnExternalsFail: true, 
                            credentialsId: 'hudson', 
                            depthOption: 'infinity', 
                            ignoreExternalsOption: true, 
                            local: '.', 
                            remote: 'https://svn.int.domain.edu/project/trunk']], 
                        quietOperation: true, 
                        workspaceUpdater: [$class: 'UpdateUpdater']
                ]
            }
        }
        stage('Run Kitchen') {       
            steps {
                def result = bat( label: '', returnStdout: true, script: 'kitchen -args %AWARD_YEAR%'  )
                
                echo result     
            }

        }

    }

}

Below is the error shown in the Jenkins Console

org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
WorkflowScript: 35: Expected a step @ line 35, column 5.
                result = bat( label: '', returnStdout: true, script: 'kitchen -args %AWARD_YEAR%'  )
       ^

1 error

    at org.codehaus.groovy.control.ErrorCollector.failIfErrors(ErrorCollector.java:310)
    at org.codehaus.groovy.control.CompilationUnit.applyToPrimaryClassNodes(CompilationUnit.java:1085)
    at org.codehaus.groovy.control.CompilationUnit.doPhaseOperation(CompilationUnit.java:603)
    at org.codehaus.groovy.control.CompilationUnit.processPhaseOperations(CompilationUnit.java:581)
    at org.codehaus.groovy.control.CompilationUnit.compile(CompilationUnit.java:558)
    at groovy.lang.GroovyClassLoader.doParseClass(GroovyClassLoader.java:298)
    at groovy.lang.GroovyClassLoader.parseClass(GroovyClassLoader.java:268)
    at groovy.lang.GroovyShell.parseClass(GroovyShell.java:688)
    at groovy.lang.GroovyShell.parse(GroovyShell.java:700)
    at org.jenkinsci.plugins.workflow.cps.CpsGroovyShell.doParse(CpsGroovyShell.java:142)
    at org.jenkinsci.plugins.workflow.cps.CpsGroovyShell.reparse(CpsGroovyShell.java:127)
    at org.jenkinsci.plugins.workflow.cps.CpsFlowExecution.parseScript(CpsFlowExecution.java:561)
    at org.jenkinsci.plugins.workflow.cps.CpsFlowExecution.start(CpsFlowExecution.java:522)
    at org.jenkinsci.plugins.workflow.job.WorkflowRun.run(WorkflowRun.java:337)
    at hudson.model.ResourceController.execute(ResourceController.java:97)
    at hudson.model.Executor.run(Executor.java:428)
Finished: FAILURE

当我按如下方式修改步骤时,脚本执行时没有错误,但不会存储退出代码,因此即使二进制可执行文件失败,管道也会显示成功。

steps {
     result = bat label: '', returnStdout: true, script: 'kitchen -args %AWARD_YEAR%'  
}

Post 脚本

还有另外两个 Whosebug 问题提出了这个特定问题,但解决方案导致了我收到的错误。

如果要捕获 sh 步骤的结果并将其分配给变量,则需要在 script 块中进行。

改变

stage('Run Kitchen') {       
    steps {
        def result = bat( label: '', returnStdout: true, script: 'kitchen -args %AWARD_YEAR%'  )
                
        echo result     
    }
}

stage('Run Kitchen') {       
    steps {
        script {
            def result = bat( label: '', returnStdout: true, script: 'kitchen -args %AWARD_YEAR%'  )
                
            echo result     
        }
    }
 }

你应该解决你现在看到的问题。