詹金斯:无法在管道阶段定义变量


106

我正在尝试创建一个声明性的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。

Answers:


101

Jenkins Pipelines的Declarative模型具有受限制的语法子集,可在stage块中使用- 有关更多信息,请参见语法指南。您可以通过将步骤包装在一个script { ... }块中来绕过该限制,但是结果,您将失去对该script块内语法,参数等的验证。


5
如果我想在脚本块之外使用该变量怎么办?
Jan Steinke '18

3
使用脚本块外部变量检查此stackoverflow.com/questions/43879733/...
塞特希甲库马尔

56

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

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

我认为您有一些多余的行是无效的...

编辑

从声明式管道模型文档中,您似乎必须使用environment声明块来声明变量,例如:

pipeline {
   environment {
     FOO = "foo"
   }

   agent none
   stages {
       stage("first") {
           sh "echo ${FOO}"
       }
   }
}

1
您还可以将环境块添加到阶段中(例如,如果您的变量取决于在先前步骤中完成的操作)。
Tereza Tomcova

34

同意@ 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"
            }
        }
    }
}

4
请注意,此示例假定jenkins已存在定义的环境变量“ ENVIRONMENT_NAME”。
艾伯托

1
脚本块可以更改环境值吗?
pitchblack408 '19

是的,您可以在脚本块中更改环境值。
NicoPaez

8

在詹金斯2.138.3中,有两种不同类型的管道。

声明性和脚本化管道。

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

jenkins管道:代理vs节点?

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

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

我从上面的代码中收到以下错误:[管道]管道的开始[管道] readMavenPom [管道]管道的结束org.jenkinsci.plugins.workflow.steps.MissingContextVariableException:必需的上下文类hudson.FilePath丢失也许您忘记了包围带有提供此功能的步骤的代码,例如:node
mancocapac

不,它按原样工作。这是一个声明式管道。代理any意味着它可以在任何节点上工作
pitchblack408

@ pitchblack408,您是对的,我在管道顶部有[agent none]。不知道您的意思是:设置环境后环境是静态的吗?可以在脚本中更改它们,例如脚本{IMAGE =“ newVal}
mancocapac

例如,查看IMAGE。管道可以或不应更改它的变量。据我了解,在定义为环境的一部分之后,应将其视为静态值。
pitchblack408

0

您正在使用声明性管道,该管道需要脚本步骤才能执行Groovy代码。与没有必要的脚本管道相比,这是一个巨大的差异。

官方文件说的情况如下:

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

pipeline {
   agent none
   stages {
       stage("first") {
           script {
               def foo = "foo" 
               sh "echo ${foo}"
           }
       }
   }
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.