Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jenkins Shared Library Global/Singleton Class

I am looking for some guidance on the design of a Jenkins Shared Library, with respect to using a class, initializing it, and then being able to use that instance in any of my vars files.

Structure

src
  - foo
   - class
     - Configuration.groovy
vars
  - cicd.groovy
  - doMore.groovy

Class

The following is a class I would like to initialize once, but then use anywhere, without having to pass it into each vars function, or reinitialize every time.

package foo.class

public class Configuration {

    public String Foo

    public String Bar    

}

Vars

In my cicd.groovy vars file, I have something like this:

#!groovy
import foo.class.Configuration

def call () {

    return initCicd()
}

def initCicd() {
    configuration = new Configuration()
    configuration.Foo = 'FOO'
    return configuration
}

But, in other vars files like doMore.groovy, I would like to use the same configuration instance.

#!groovy
import foo.class.Configuration

def call () {

    println configuration.Foo
}

Is there a Singleton pattern that that works in Jenkins Shared Library, or a way to reference an instance across vars files or steps? If possible, please share an example.

Thanks!

like image 988
ISZ Avatar asked Feb 17 '18 15:02

ISZ


1 Answers

You can simply use Groovy's @Singleton annotation for your Configuration class and use Configuration.instance wherever you want to access configuration settings. Consider following example:

.
├── src
│   └── foo
│       └── Configuration.groovy
└── vars
    ├── cicd.groovy
    └── doMore.groovy

src/foo/Configuration.groovy

package foo

@Singleton
class Configuration {
    public String foo = 'foo_123'
    public String bar = 'bar_456'
}

vars/cicd.groovy

#!groovy

import foo.Configuration

def call() {
    return initCicd()
}

def initCicd() {
    println Configuration.instance.foo
    return Configuration.instance
}

vars/doMore.groovy

#!groovy

import foo.Configuration

def call() {
    println Configuration.instance.bar
}

In the pipeline script I simply call:

cicd()
doMore()

And I get something like that in the console log:

Loading library default_jenkins_libs@master
Attempting to resolve master from remote references...
 > git --version # timeout=10
 > git ls-remote -h -t file:///var/jenkins_home/libraries # timeout=10
Found match: refs/heads/master revision 4fa988ccde542d77d19febd72f532ef996971a5d
 > git rev-parse --is-inside-work-tree # timeout=10
Fetching changes from the remote Git repository
 > git config remote.origin.url file:///var/jenkins_home/libraries # timeout=10
Fetching without tags
Fetching upstream changes from file:///var/jenkins_home/libraries
 > git --version # timeout=10
 > git fetch --no-tags --progress file:///var/jenkins_home/libraries +refs/heads/*:refs/remotes/origin/*
Checking out Revision 4fa988ccde542d77d19febd72f532ef996971a5d (master)
 > git config core.sparsecheckout # timeout=10
 > git checkout -f 4fa988ccde542d77d19febd72f532ef996971a5d
Commit message: "update"
 > git rev-list --no-walk 39890b4ca39bf32ebde8c7ad143b110bf16cf6b3 # timeout=10
[Pipeline] echo
foo_123
[Pipeline] echo
bar_456
[Pipeline] End of Pipeline
Finished: SUCCESS

The one downside of using singletons is that they can get modified anywhere and this change is populated to all callers.

like image 54
Szymon Stepniak Avatar answered Oct 05 '22 15:10

Szymon Stepniak