【问题标题】:Jenkins: Cannot define variable in pipeline stage詹金斯:无法在管道阶段定义变量
【发布时间】:2017-02-11 11:20:04
【问题描述】:

我正在尝试创建一个声明性 Jenkins 管道脚本,但在简单的变量声明方面遇到了问题。

这是我的脚本:

pipeline {
   agent none
   stages {
       stage("first") {
           def foo = "foo" // fails with "WorkflowScript: 5: Expected a step @ line 5, column 13."
           sh "echo ${foo}"
       }
   }
}

但是,我收到此错误:

org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
WorkflowScript: 5: Expected a step @ line 5, column 13.
           def foo = "foo"
           ^

我正在使用 Jenkins 2.7.4 和 Pipeline 2.4。

【问题讨论】:

    标签: jenkins groovy jenkins-pipeline


    【解决方案1】:

    试试这个声明式管道,它的工作原理

    pipeline {
       agent any
        stages {
          stage("first") {
            steps{
              script {
               def foo = "foo" 
               sh "echo ${foo}"
                  }
                }
              }
            }
           }
    

    【讨论】:

      【解决方案2】:

      你可以定义变量 global ,但是使用这个变量时必须写在脚本块中。

      def foo="foo"
      pipeline {
      agent none
      stages {
         stage("first") {
            script{
                sh "echo ${foo}"
            }
          }
        }
      }
      

      【讨论】:

      • 如何在一个阶段中操作变量?例如。如果我想在stage("first") 中分配"bar" 的值怎么办?
      【解决方案3】:

      我认为错误不是来自指定的行,而是来自前 3 行。试试这个:

      node {
         stage("first") {
           def foo = "foo"
           sh "echo ${foo}"
         }
      }
      

      我认为您有一些无效的额外行...

      从 declaractive pipeline model documentation 看来,您似乎必须使用 environment 声明块来声明您的变量,例如:

      pipeline {
         environment {
           FOO = "foo"
         }
      
         agent none
         stages {
             stage("first") {
                 sh "echo ${FOO}"
             }
         }
      }
      

      【讨论】:

      • 您还可以将环境块添加到阶段(例如,如果您的变量依赖于之前步骤中所做的某些事情)。
      【解决方案4】:

      同意@Pom12、@abayer。要完成答案,您需要添加脚本块

      试试这样的:

      pipeline {
          agent any
          environment {
              ENV_NAME = "${env.BRANCH_NAME}"
          }
      
          // ----------------
      
          stages {
              stage('Build Container') {
                  steps {
                      echo 'Building Container..'
      
                      script {
                          if (ENVIRONMENT_NAME == 'development') {
                              ENV_NAME = 'Development'
                          } else if (ENVIRONMENT_NAME == 'release') {
                              ENV_NAME = 'Production'
                          }
                      }
                      echo 'Building Branch: ' + env.BRANCH_NAME
                      echo 'Build Number: ' + env.BUILD_NUMBER
                      echo 'Building Environment: ' + ENV_NAME
      
                      echo "Running your service with environemnt ${ENV_NAME} now"
                  }
              }
          }
      }
      

      【讨论】:

      • 请注意,此示例假定 jenkins 可以访问已定义的环境变量“ENVIRONMENT_NAME”。
      • 脚本块可以改变环境值吗?
      • 是的,您可以更改脚本块内的环境值。
      【解决方案5】:

      您正在使用 Declarative Pipeline,它需要 脚本步骤 来执行 Groovy 代码。与不需要这样做的Scripted Pipeline 相比,这是一个巨大的差异。

      official documentation 表示以下内容:

      脚本步骤采用脚本管道块并执行 在声明式管道中。

      pipeline {
         agent none
         stages {
             stage("first") {
                 script {
                     def foo = "foo" 
                     sh "echo ${foo}"
                 }
             }
         }
      }
      

      【讨论】:

        【解决方案6】:

        在 Jenkins 2.138.3 中有两种不同类型的管道。

        声明式和脚本式管道。

        “声明式管道是管道DSL的新扩展(它基本上是一个只有一个步骤的管道脚本,一个带有参数的管道步骤(称为指令),这些指令应该遵循特定的语法。这种新格式的要点是它更严格,因此对于管道新手来说应该更容易,允许图形编辑等等。 脚本化管道是高级需求的后备方案。”

        jenkins pipeline: agent vs node?

        这是在声明式管道中使用环境变量和全局变量的示例。据我所知,环境在设置后是静态的。

        def  browser = 'Unknown'
        
        pipeline {
            agent any
            environment {
            //Use Pipeline Utility Steps plugin to read information from pom.xml into env variables
            IMAGE = readMavenPom().getArtifactId()
            VERSION = readMavenPom().getVersion()
        
        
            }
            stages {
                stage('Example') {
                    steps {
                        script {
                            browser = sh(returnStdout: true, script: 'echo Chrome')
                        }
                    }
                }
                stage('SNAPSHOT') {
                        when {
                            expression { 
                                return !env.JOB_NAME.equals("PROD") && !env.VERSION.contains("RELEASE")
                            }
                        }
                        steps {
                            echo "SNAPSHOT"
                            echo "${browser}"
                        }
                    }
                    stage('RELEASE') {
                        when {
                            expression { 
                                return !env.JOB_NAME.equals("TEST") && !env.VERSION.contains("RELEASE")
                            }
                        }
                        steps {
                            echo "RELEASE"
                            echo "${browser}"
                        }
                    }
            }//end of stages 
        }//end of pipeline
        

        【讨论】:

        • 我从上面的代码中得到以下错误: [Pipeline] Start of Pipeline [Pipeline] readMavenPom [Pipeline] End of Pipeline org.jenkinsci.plugins.workflow.steps.MissingContextVariableException: required context class hudson. FilePath is missing 也许你忘了用提供这个的步骤包围代码,例如:node
        • 不,它按原样工作。这是一个声明性管道。代理 any 意味着它可以在任何节点上工作
        • @pitchblack408,你说得对,我的管道顶部有 [agent none]。不知道你的意思是:环境在设置后是静态的?它们可以在脚本中更改,例如脚本{ IMAGE = "newVal}
        • 例如,看IMAGE。它不是可以或应该由管道更改的变量。我的理解是,在定义为环境的一部分后,它会被视为静态值。
        【解决方案7】:

        Jenkins Pipelines 的声明性模型有一个受限制的语法子集,它允许在 stage 块 - see the syntax guide for more info 中使用。您可以通过将步骤包装在 script { ... } 块中来绕过该限制,但结果是,您将失去对 script 块中语法、参数等的验证。

        【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-10-08
        • 2018-12-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-01-09
        • 2018-11-28
        相关资源
        最近更新 更多