3

I am studying Jenkins Pipeline Global Lib functionality. It seems pretty handy however due to its global nature any harmful change will affect all the jobs. Thus I want to be able to test it before pushing to master on a different branch.

Is there a way to specify a branch from which I want to to include the global lib sources for a particular job?

UPDATE. I tried a workaround with direct git clone from the test branch then load my library file explicitly replacing the automatically loaded one. The problem comes when this lib uses some other class from the src/. Because in this case its pre-loaded version from master is always used.

So in the conditions below it runs common.groovy from feature-test but prints Hello from master!!!! when b.dummy() is called.

Pipeline Script in Jenkins:

node('myhost'){
    git url: 'ssh://10.0.0.1:12345/workflowLibs.git',
        branch: 'feature-test'

    dir ('src'){
        load 'com/foo/Base.groovy'
    }
    dir ('vars'){
        common = load 'common.groovy'
    }
}

println common.dummy()

vars/common.groovy (feature-test):

package com.foo
def dummy(){
    def b = new com.foo.Base()
    b.dummy()
}

src/com/foo/Base.groovy (master):

package com.foo
def dummy(){
    return 'Hello from master!!!!'
}

src/com/foo/Base.groovy (feature-test):

package com.foo
def dummy(){
    return 'Hello from feature-test!!!!'
}
izzekil
  • 5,781
  • 2
  • 36
  • 38

1 Answers1

4

As far as I'm aware, this isn't possible — scripts pushed to this repo can't be versioned by having different branches.

There are a few alternative approaches you could take, which involve hosting your scripts in an external repo (i.e. not with the Global Lib repo):


You could use the Pipeline Remote Loader plugin, which allows you to pull Pipeline scripts from a remote repo, e.g.

def p = fileLoader.fromGit('bar/common.groovy', 
          'https://example.com/foo/pipelines.git',
          'test-branch', null, '')
p.doSomething()

You can also use this plugin to easily load multiple Pipeline scripts from the same repo.


Alternatively, you could check out your script Git repo within a Pipeline execution and load a script directly:

stage 'Load scripts'
def p
dir('tmp') {
    git url: 'https://example.com/foo/pipelines.git',
        branch: 'test-branch'
    p = load 'bar/common.groovy'
}

stage 'Do something'
p.doSomething()

If you want to keep on using the Global Lib repo, you could use the above techniques for testing the scripts, and then set up a Jenkins job to push your script changes into the master Global Lib repo.

Christopher Orr
  • 110,418
  • 27
  • 198
  • 193
  • Work is planned on bringing together the best features of Global Lib and Remote Loader, but for now these are your options. – Jesse Glick Feb 22 '16 at 14:29
  • Looks cool, thanks! However I didn't get if there is any diiference except convenient interface from git+load? Any difference in the load procedure? – izzekil Feb 24 '16 at 09:06
  • BTW, is there a way to bring some remote directories into the current script's classpath, at least for the loading phase? Say I have two library groovy scripts that shares some code. How can I include this common part within that scripts? Plain `import` can't locate the files. I tried manipulating with current classpath via `this.class.classLoader.rootLoader` but it's `null`. – izzekil Feb 24 '16 at 16:06
  • I created a separate question instead http://stackoverflow.com/q/35637833/1579623 – izzekil Feb 26 '16 at 23:37
  • Global Pipeline Library now supports specifying version, https://github.com/jenkinsci/workflow-cps-global-lib-plugin/blob/master/README.md, and is by far more convenient that Pipeline Remote Loader. – luka5z Oct 24 '16 at 20:24