3

According to another answer if you define a variable without def it becomes "global" and thus you can access it from anywhere in the script. How can I do this with a method (as there is no definition without def AFAIK)?

For the record: I'm defining Jenkins pipelines and want to access some "global" methods outside from various stages

Szymon Stepniak
  • 40,216
  • 10
  • 104
  • 131
Uko
  • 13,134
  • 6
  • 58
  • 106

2 Answers2

6

You can define any method in your Jenkinsfile outside pipeline {}, e.g.

@NonCPS
def pomVersion() {
    def matcher = readFile('pom.xml') =~ '<version>(.+)</version>'
    return matcher ? matcher[1][1] : null
}

pipeline {
    agent any

    stages {
        stage('Build') {
            steps {
                sh "sed -i.bak -e 's|\${appVersion}|'${pomVersion()}'|g' dep_pom.xml"            
                sh 'mvn clean -U install -DdeploymentContext=test -f dep_pom.xml'
            }
            post {
                success {
                    junit '**/target/**/*.xml'
                }
            }
        }
    }
}

Here is some exemplary script that defines pomVersion() method that reads version from pom.xml file. It can be accessed in any stage and any step of the pipeline.

Regarding your statement that:

if you define a variable without def it becomes "global" and thus you can access it from anywhere in the script

it's not like that actually. Groovy script is compiled to a class that extends groovy.lang.Script class. It uses bindings structure (think of it as a Map<String,Object>) that stores all variables used in the script. This mechanism allows e.g. to share same bindings between two separate scripts if they are run using same GroovyShell instance.

Szymon Stepniak
  • 40,216
  • 10
  • 104
  • 131
  • Your `pomVersion` should probably be marked with `@NonCPS` as [`java.util.regex.Matcher` is not `Serializable`](https://docs.oracle.com/javase/8/docs/api/java/util/regex/Matcher.html). – mkobit Jan 18 '18 at 17:01
2

A simple way of doing this would be to use the Shared Libraries feature within Jenkins to define additional methods in a separate file. This is detailed in a blog and talk by Brent Laster.

  • 1
    This is true. But imagine that I just have one method which is project specific and simplifies deployment. Does it make sense to create a shared library just for that? – Uko Jan 18 '18 at 11:03
  • If it's going to just be the one, probably not. I can't quite recall, but does Jenkins have support for Groovy Closures within the sandbox yet? – michaelranaldo Jan 18 '18 at 11:13