Reputation: 4879
I'm trying to create a declarative Jenkins pipeline script but having issues with simple variable declaration.
Here is my script:
pipeline {
agent none
stages {
stage("first") {
def foo = "foo" // fails with "WorkflowScript: 5: Expected a step @ line 5, column 13."
sh "echo ${foo}"
}
}
}
However, I get this error:
org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
WorkflowScript: 5: Expected a step @ line 5, column 13.
def foo = "foo"
^
I'm on Jenkins 2.7.4 and Pipeline 2.4.
Upvotes: 145
Views: 312706
Reputation: 1419
To use var in Jenkins --
Some more/summarized examples regarding:
- local var vs env var;
- var scope;
- string interpolation;
def var_D = "Demo"
pipeline {
agent any
environment {
var_E = "Egg"
}
stages {
stage("R1") {
steps {
script {
def var_A = "Apple"
sh "echo ${var_A}" // Apple // this is string interpolation -- injected by groovy
sh "echo $var_A" // Apple // same^ groovy syntax https://stackoverflow.com/questions/33880220/when-do-you-need-curly-braces-for-variable-substitution-in-gradle
sh 'echo ${var_A}' // // no such env var in bash (its an local var in groovy) -- so its empty
sh 'echo $var_A' // // same^
echo "${var_A}" // Apple
echo "$var_A" // Apple
echo '${var_A}' // ${var_A} // single quote disables string interpolation
echo '$var_A' // $var_A
}
}
}
stage("R2") {
environment {
var_C = "Cammel"
}
steps {
sh "echo ${var_C}" // Cammel // ~~~//repeat: this is string interpolation -- injected by groovy
sh "echo $var_C" // Cammel // ~~~//repeat: same^ groovy syntax https://stackoverflow.com/questions/33880220/when-do-you-need-curly-braces-for-variable-substitution-in-gradle
sh 'echo ${var_C}' // Cammel // https://stackoverflow.com/questions/8748831/when-do-we-need-curly-braces-around-shell-variables
sh 'echo $var_C' // Cammel // bash is accessing the env var -- its bash not groovy because >"single quote disables string interpolation"
echo "${var_C}" // Cammel // same^
echo "$var_C" // Cammel // same^
echo '${var_C}' // ${var_C}
echo '$var_C' // $var_C
}
}
// ;wrong; stage("R3") {
// ;wrong; steps {
// ;wrong; script {
// ;wrong; def var_B = "Banana"
// ;wrong; }
// ;wrong; sh "echo ${var_B}" // out of scope -- groovy.lang.MissingPropertyException: No such property: var_B for class: groovy.lang.Binding
// ;wrong; }
// ;wrong; }
// ;wrong; stage("R3.2") {
// ;wrong; steps {
// ;wrong; script {
// ;wrong; def var_B = "Banana"
// ;wrong; }
// ;wrong; sh "echo zzz"
// ;wrong; script {
// ;wrong; sh "echo ${var_B}" // out of scope -- groovy.lang.MissingPropertyException: No such property: var_B for class: groovy.lang.Binding
// ;wrong; }
// ;wrong; }
// ;wrong; }
stage("R4") {
steps {
sh "echo ${var_D}" // Demo // global scope
sh "echo ${var_E}" // Egg // global scope
sh 'echo ${var_D}' // // >"no such env var in bash (its an local var in groovy)"
sh 'echo ${var_E}' // Egg // global scope
// ;wrong; sh "echo ${var_A}" // out of scope -- groovy.lang.MissingPropertyException: No such property: var_A for class: groovy.lang.Binding
script {
sh "echo ${var_D}" // Demo // same^ (script scope wont make diff)
sh "echo ${var_E}" // Egg // same^
sh 'echo ${var_D}' // // same^
sh 'echo ${var_E}' // Egg // same^
// ;wrong; sh "echo ${var_A}" // out of scope -- groovy.lang.MissingPropertyException: No such property: var_A for class: groovy.lang.Binding
}
}
}
}
}
// [Output]
//
// Started by user nor
// [Pipeline] Start of Pipeline
// [Pipeline] node
// Running on Jenkins in C:\Users\Amplify\AppData\Local\Jenkins\.jenkins\workspace\Test1
// [Pipeline] {
// [Pipeline] withEnv
// [Pipeline] {
// [Pipeline] stage
// [Pipeline] { (R1)
// [Pipeline] script
// [Pipeline] {
// [Pipeline] sh
// + echo Apple
// Apple
// [Pipeline] sh
// + echo Apple
// Apple
// [Pipeline] sh
// + echo
//
// [Pipeline] sh
// + echo
//
// [Pipeline] echo
// Apple
// [Pipeline] echo
// Apple
// [Pipeline] echo
// ${var_A}
// [Pipeline] echo
// $var_A
// [Pipeline] }
// [Pipeline] // script
// [Pipeline] }
// [Pipeline] // stage
// [Pipeline] stage
// [Pipeline] { (R2)
// [Pipeline] withEnv
// [Pipeline] {
// [Pipeline] sh
// + echo Cammel
// Cammel
// [Pipeline] sh
// + echo Cammel
// Cammel
// [Pipeline] sh
// + echo Cammel
// Cammel
// [Pipeline] sh
// + echo Cammel
// Cammel
// [Pipeline] echo
// Cammel
// [Pipeline] echo
// Cammel
// [Pipeline] echo
// ${var_C}
// [Pipeline] echo
// $var_C
// [Pipeline] }
// [Pipeline] // withEnv
// [Pipeline] }
// [Pipeline] // stage
// [Pipeline] stage
// [Pipeline] { (R4)
// [Pipeline] sh
// + echo Demo
// Demo
// [Pipeline] sh
// + echo Egg
// Egg
// [Pipeline] sh
// + echo
//
// [Pipeline] sh
// + echo Egg
// Egg
// [Pipeline] script
// [Pipeline] {
// [Pipeline] sh
// + echo Demo
// Demo
// [Pipeline] sh
// + echo Egg
// Egg
// [Pipeline] sh
// + echo
//
// [Pipeline] sh
// + echo Egg
// Egg
// [Pipeline] }
// [Pipeline] // script
// [Pipeline] }
// [Pipeline] // stage
// [Pipeline] }
// [Pipeline] // withEnv
// [Pipeline] }
// [Pipeline] // node
// [Pipeline] End of Pipeline
// Finished: SUCCESS
Upvotes: 0
Reputation: 22701
Use function !
pipeline {
agent any
stages {
stage("first") {
steps{
script {
sh "echo ${foo()}"
}
}
}
}
}
def foo() {
return "hello this is logic code ${env.param1}"
}
Upvotes: 0
Reputation: 47
Try this declarative pipeline, its working
pipeline {
agent any
stages {
stage("first") {
steps{
script {
def foo = "foo"
sh "echo ${foo}"
}
}
}
}
}
Upvotes: 2
Reputation: 63
you can define the variable global , but when using this variable must to write in script block .
def foo="foo"
pipeline {
agent none
stages {
stage("first") {
script{
sh "echo ${foo}"
}
}
}
}
Upvotes: 3
Reputation: 7880
I think error is not coming from the specified line but from the first 3 lines. Try this instead :
node {
stage("first") {
def foo = "foo"
sh "echo ${foo}"
}
}
I think you had some extra lines that are not valid...
From declaractive pipeline model documentation, it seems that you have to use an environment
declaration block to declare your variables, e.g.:
pipeline {
environment {
FOO = "foo"
}
agent none
stages {
stage("first") {
sh "echo ${FOO}"
}
}
}
Upvotes: 77
Reputation: 1139
Agree with @Pom12, @abayer. To complete the answer you need to add script block
Try something like this:
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"
}
}
}
}
Upvotes: 56
Reputation: 5276
You are using a Declarative Pipeline which requires a script-step to execute Groovy code. This is a huge difference compared to the Scripted Pipeline where this is not necessary.
The official documentation says the following:
The script step takes a block of Scripted Pipeline and executes that in the Declarative Pipeline.
pipeline {
agent none
stages {
stage("first") {
script {
def foo = "foo"
sh "echo ${foo}"
}
}
}
}
Upvotes: 4
Reputation: 2983
In Jenkins 2.138.3 there are two different types of pipelines.
Declarative and Scripted pipelines.
"Declarative pipelines is a new extension of the pipeline DSL (it is basically a pipeline script with only one step, a pipeline step with arguments (called directives), these directives should follow a specific syntax. The point of this new format is that it is more strict and therefore should be easier for those new to pipelines, allow for graphical editing and much more. scripted pipelines is the fallback for advanced requirements."
jenkins pipeline: agent vs node?
Here is an example of using environment and global variables in a Declarative Pipeline. From what I can tell enviroment are static after they are set.
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
Upvotes: 15
Reputation: 1759
The Declarative model for Jenkins Pipelines has a restricted subset of syntax that it allows in the stage
blocks - see the syntax guide for more info. You can bypass that restriction by wrapping your steps in a script { ... }
block, but as a result, you'll lose validation of syntax, parameters, etc within the script
block.
Upvotes: 130