Jenkins 有没有一种方法可以在声明性管道中以编程方式注入post操作

Jenkins 有没有一种方法可以在声明性管道中以编程方式注入post操作,jenkins,groovy,jenkins-pipeline,Jenkins,Groovy,Jenkins Pipeline,我需要在几个阶段之间共享一些代码,这也需要添加post操作。为此,我考虑将所有内容都放在一个方法中,该方法将从 pipeline { stages { stage('Some') { steps { script { commonCode() } } } } } 但是,我不确定如何在fromcommonCode中安装post操作。文档中没有提到任何东西。看看代码,这

我需要在几个阶段之间共享一些代码,这也需要添加post操作。为此,我考虑将所有内容都放在一个方法中,该方法将从

pipeline {
    stages {
        stage('Some') {
            steps {
                script { commonCode() }
            }
        }
     }
}
但是,我不确定如何在from
commonCode
中安装post操作。文档中没有提到任何东西。看看代码,这意味着DSL基本上只是在玩一个散列映射,但我不知道是否可以从该方法访问它并动态修改

基本上,我想在
commonCode
中这样做:

if (something) {
    attachPostAction('always', { ... })
} else {
    attachPostAction('failure', { ... })
}
到目前为止,唯一有效的方法是在
commonCode
中,我执行以下操作:

try {
...
onSuccess()
} catch (e) {
onError()
} finally {
onAlways()
}

但是我想知道是否有一种更优雅的方法…

您可以在
管道
块之外使用常规groovy脚本。虽然我还没有尝试过,但您应该能够在外部定义一个方法,然后从管道内部调用它。但是方法调用不能作为步骤调用。您需要将其包装在脚本步骤中。但是
post
操作的步骤与
步骤{}
块的步骤相同,因此如果可以在
步骤中使用它,则可以在post部分中使用它。你需要仔细观察范围界定,否则你最终会试图找出为什么某些地方的东西是空的


您还可以使用共享库。您可以在共享库中定义一个步骤,然后像
步骤{}
块或一个post块中的任何其他步骤一样使用它

您可以在
管道
块之外使用常规groovy脚本。虽然我还没有尝试过,但您应该能够在外部定义一个方法,然后从管道内部调用它。但是方法调用不能作为步骤调用。您需要将其包装在脚本步骤中。但是
post
操作的步骤与
步骤{}
块的步骤相同,因此如果可以在
步骤中使用它,则可以在post部分中使用它。你需要仔细观察范围界定,否则你最终会试图找出为什么某些地方的东西是空的


您还可以使用共享库。您可以在共享库中定义一个步骤,然后像
步骤{}
块或一个post块中的任何其他步骤一样使用它

现在我更好地理解了这个问题(我希望)

这是一个非常有趣的想法——在前几个阶段动态生成您的post操作

结果证明这真的很容易。我尝试了一个选项(success),它将各种闭包存储在一个列表中,然后遍历该列表并在post操作中运行所有闭包。然后我做了另一个(失败),我只是将一个闭包保存为变量并运行它。两者都很有效

下面是执行此操作的代码。取消注释
错误
行以模拟失败的生成

def postSuccess = []
def postFailure

pipeline {
  agent any
  stages {
    stage('Success'){
        steps {
            script {
                println "Configure Success Post Steps"
                postSuccess[0] = {echo "This is a successful build"}
                postSuccess[1] = {
                                    echo "Running multiple steps"
                                    sh "ls -latr"
                                  }
            }
        }
    }
    stage('Failure'){
        steps {
            script {
                println "Configure Failure Post Steps"
                postFailure = {
                    echo "This build failed"
                    echo "Running multiple steps for failure"
                    sh """
                        whoami
                        pwd
                    """
                }
            }
//            error "Simulate a failed build"   //uncomment this line to make the build fail
        }
    }
  } // stages

    post {
        success {
            echo "SUCCESS"
            script {
                for (def my_closure in postSuccess) {
                    my_closure()
                }
            }
        }
        failure {
            echo "FAILURE!"
            script {
                postFailure()
            }
        }
    }
} // pipeline

现在我更好地理解了这个问题(我希望)

这是一个非常有趣的想法——在前几个阶段动态生成您的post操作

结果证明这真的很容易。我尝试了一个选项(success),它将各种闭包存储在一个列表中,然后遍历该列表并在post操作中运行所有闭包。然后我做了另一个(失败),我只是将一个闭包保存为变量并运行它。两者都很有效

下面是执行此操作的代码。取消注释
错误
行以模拟失败的生成

def postSuccess = []
def postFailure

pipeline {
  agent any
  stages {
    stage('Success'){
        steps {
            script {
                println "Configure Success Post Steps"
                postSuccess[0] = {echo "This is a successful build"}
                postSuccess[1] = {
                                    echo "Running multiple steps"
                                    sh "ls -latr"
                                  }
            }
        }
    }
    stage('Failure'){
        steps {
            script {
                println "Configure Failure Post Steps"
                postFailure = {
                    echo "This build failed"
                    echo "Running multiple steps for failure"
                    sh """
                        whoami
                        pwd
                    """
                }
            }
//            error "Simulate a failed build"   //uncomment this line to make the build fail
        }
    }
  } // stages

    post {
        success {
            echo "SUCCESS"
            script {
                for (def my_closure in postSuccess) {
                    my_closure()
                }
            }
        }
        failure {
            echo "FAILURE!"
            script {
                postFailure()
            }
        }
    }
} // pipeline

我想我的问题可能不太清楚。我知道我可以在
steps
post
中使用步骤和其他方法(前提是我在
脚本中包装了一些)。我的问题是:我可以在
步骤中做一些事情,通过编程附加新的
post
操作。啊。。。这不是我所理解的。对不起,误会了。我想知道您是否可以使用散列或列表来存储一些您希望在post中运行的东西的闭包,然后在到达那里时运行这些闭包。我看看以后能不能搞乱这件事。我想我的问题可能不太清楚。我知道我可以在
steps
post
中使用步骤和其他方法(前提是我在
脚本中包装了一些)。我的问题是:我可以在
步骤中做一些事情,通过编程附加新的
post
操作。啊。。。这不是我所理解的。对不起,误会了。我想知道您是否可以使用散列或列表来存储一些您希望在post中运行的东西的闭包,然后在到达那里时运行这些闭包。我等会儿再看能不能搞糟。哇,这是一个很酷的方法!是否有可能将其扩展到共享库?这取决于您希望如何实现,是的,我认为这可能会奏效。你可以从一个库中返回你想要的,然后把它放到post变量中。哇,这是一个非常酷的方法!是否有可能将其扩展到共享库?这取决于您希望如何实现,是的,我认为这可能会奏效。您可以从库中返回所需内容,并将其放入post变量中。