0
votes

I have a map of data that I have extracted during a Groovy pipeline script. In the next stage of the pipeline I would like to loop through the data and insert in the environmental variables for usage.

This stage includes a ant command that uses a build xml to retrieve the environmental ${env.appName} parameter. (see xml example below)

<project ...>
   ...
    <entry ...value="${env.appName}/>
    <entry ...value="${env.version}/>
   ...
</project>

I am going through the key value pair of the map.

pipeline {
  agent any
  stages{
    stage ('Data') {
     steps{ 
      scripts {
        def map = [app1: "01.01", app2: "02.02"]
       }
      }
    }
   stage ('Loop'){
     steps {
      withAnt(){
       sh '''
          {map.collect{ k,v -> "appName=${k} version=${v}"}}
          ant -buildfile ~/build.xml
          ...
          '''
        }
      }
    }
  }
}

However, I get an error:

line 3 : {map.collect{ k,v -> "appName=${k} version=${v}"}}: bad substitution.

Is it possible to loop a map in the sh block? Is there a way to do this so that the ant command is done on each element of the map?

2
Why do you write groovy code for the shell? I don't do jenkins, but i'd guess this has to go around the innermost sh. Then use """ instead of ''' to have replacement. - cfrick
can you refer to a variable between different stages in declarative pipeline? - SSF

2 Answers

0
votes
...
withAnt{
   def cmd = map.collect{k,v-> "\n appName=${k}\n version=${v}\n ant -buildfile ~/build.xml"}.join()
   sh cmd
}

for the map [app1: "01.01", app2: "02.02"] the cmd variable will have:

 appName=app1
 version=01.01
 ant -buildfile ~/build.xml
 appName=app2
 version=02.02
 ant -buildfile ~/build.xml

or you could include expression into multiline evaluated (doublequoted) string:

sh """
....
${ map.collect{k,v-> "\n appName=${k}\n version=${v}\n ant -buildfile ~/build.xml"}.join() }
....
"""
0
votes

In order to pass the values between stages, I loaded the values in a file and loaded the file. Then the values were accessible in the shell.

pipeline {
  agent any 
  stages {
   stage ('Data') {
    steps {
      script {
        ...
        map. each{ key,value ->
                    writeFile ([file: filename, text: "env.App=\"${key}\"\n"])
                    def content = readFile filename
                    writeFile([fiel: filename, text: "env.Version=\"${value}\"\n"])}
        }
       }
      }
     }
   stage ('Loop') {
      ...
      load "filename"
      sh '''
      echo $App
      '''
      ...
   }
  }
}