【问题标题】:Declarative pipeline when condition in post发布条件时的声明性管道
【发布时间】:2022-05-13 19:39:50
【问题描述】:

就 Jenkins 中的声明性管道而言,我在使用 when 关键字时遇到了问题。

我不断收到错误No such DSL method 'when' found among steps。我对 Jenkins 2 声明性管道有点陌生,我认为我不会将脚本化管道与声明性管道混为一谈。

此管道的目标是在成功运行 Sonar 后运行 mvn deploy 并发送失败或成功的邮件通知。我只希望在 master 或 release 分支上部署工件。

我遇到困难的部分在 post 部分。 通知 阶段运行良好。请注意,我可以在没有 when 子句的情况下使用它,但确实需要它或等效项。

pipeline {
  agent any
  tools {
    maven 'M3'
    jdk 'JDK8'
  }
  stages {
    stage('Notifications') {
      steps {
        sh 'mkdir tmpPom'
        sh 'mv pom.xml tmpPom/pom.xml'
        checkout([$class: 'GitSCM', branches: [[name: 'origin/master']], doGenerateSubmoduleConfigurations: false, submoduleCfg: [], userRemoteConfigs: [[url: 'https://repository.git']]])
        sh 'mvn clean test'
        sh 'rm pom.xml'
        sh 'mv tmpPom/pom.xml ../pom.xml'
      }
    }
  }
  post {
    success {
      script {
        currentBuild.result = 'SUCCESS'
      }
      when { 
        branch 'master|release/*' 
      }
      steps {
        sh 'mvn deploy'
      }     
      sendNotification(recipients,
        null,             
        'https://link.to.sonar',
        currentBuild.result,
      )
    }
    failure {
      script {
        currentBuild.result = 'FAILURE'
      }    
      sendNotification(recipients,
        null,             
        'https://link.to.sonar',
        currentBuild.result
      )
    }
  }
}

【问题讨论】:

  • 确实,您目前在全局帖子块中时无法使用。 'When' 必须在阶段指令中使用。使用 if else 是一个合乎逻辑的选择,但您需要在声明性管道中添加一个脚本块来完成这项工作:检查 stackoverflow.com/questions/49559882/…

标签: jenkins


【解决方案1】:

在声明性管道的documentation 中,提到不能在post 块中使用whenwhen 只允许在阶段指令内。 所以你可以做的是在script 中使用if 测试条件:

post {
success {
  script {
    if (env.BRANCH_NAME == 'master')
        currentBuild.result = 'SUCCESS'
  }
 }
// failure block
}

【讨论】:

  • 可能需要使用${env.BRANCH_NAME} 而不是${GIT_LOCAL_BRANCH}
  • 如果您使用的是 windows 框,则需要在其周围添加语音标记"${env.BRANCH_NAME}"
  • 对我来说,这仅适用于在没有${} 的情况下编写变量。这是 Jenkins 行为的最新变化吗?
  • 这应该被编辑为使用if (env.BRANCH_NAME == 'master')
【解决方案2】:

使用 GitHub 存储库和 Pipeline plugin 我有一些类似的东西:

pipeline {
  agent any
  stages {
    stage('Build') {
      steps {
        sh '''
          make
        '''
      }
    }
  }
  post {
    always {
      sh '''
        make clean
      '''
    }
    success {
      script {
        if (env.BRANCH_NAME == 'master') {
          emailext (
            to: 'engineers@green-planet.com',
            subject: "${env.JOB_NAME} #${env.BUILD_NUMBER} master is fine",
            body: "The master build is happy.\n\nConsole: ${env.BUILD_URL}.\n\n",
            attachLog: true,
          )
        } else if (env.BRANCH_NAME.startsWith('PR')) {
          // also send email to tell people their PR status
        } else {
          // this is some other branch
        } 
      }
    }     
  }
}

这样,可以根据正在构建的分支类型发送通知。有关详细信息,请参阅 pipeline model definition 以及服务器上可用的全局变量引用 http://your-jenkins-ip:8080/pipeline-syntax/globals#env

【讨论】:

    【解决方案3】:

    post 遇到了同样的问题。通过使用@groovy.transform.Field 注释变量来解决它。这是基于我在 Jenkins 文档中为 defining global variables 找到的信息。

    例如

    #!groovy
    
    pipeline {
        agent none
        stages {
            stage("Validate") {
                parallel {
                    stage("Ubuntu") {
                        agent {
                            label "TEST_MACHINE"
                        }
                        steps {{
                            sh "run tests command"
                            recordFailures('Ubuntu', 'test-results.xml')
                            junit 'test-results.xml'
                        }
                    }
                }
            }
        }
        post { 
            unsuccessful { 
                notify()
            }
        }
    }
    
    // Make testFailures global so it can be accessed from a 'post' step
    @groovy.transform.Field
    def testFailures = [:]
    
    def recordFailures(key, resultsFile) {
        def failures = ... parse test-results.xml script for failures ...
        if (failures) {
            testFailures[key] = failures
        }
    }
    
    def notify() {
        if (testFailures) {
            ... do something here ...
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-06-01
      • 2022-01-16
      • 2019-03-18
      • 2022-06-20
      • 1970-01-01
      • 1970-01-01
      • 2021-03-01
      相关资源
      最近更新 更多