jenkinsjenkins-pipelinejenkins-groovyjenkins-shared-libraries

Import class from shared library in Jenkinsfile


I have a shared library repo with this structure:

(root)
+- src             
|   +- com
|       +- company
|           +- DeploySteps.groovy
+- vars
|   +- MainDeploySteps.groovy

This library importing to job via Jenkinsfile as follows:

library identifier: 'jenkinslib@master', retriever: modernSCM(
     [$class       : 'GitSCMSource',
      remote       : 'git@url.to.git:jenkinslib.git',
      credentialsId: 'jenkins-credentials'])

Class in repo in src/com/company/DeploySteps.groovy has a method (for example CheckoutSCM) which I want include in Jenkinsfile.

DeploySteps.groovy:

def CheckoutSCM() {
    useful steps here
}

Is there a possible include this particular method in Jenkinsfile like

import com.company.DeploySteps

And then use it like:

CheckoutSCM('repo-here')

In Jenkinsfile later? I read documentation many times but no found answer is there possible import something from src folder, not only from vars.

Why I am asking because now when import: import com.company.DeployUtils and then try invoke method CheckoutSCM() see the error in Jenkins console output:

java.lang.NoSuchMethodError: No such DSL method 'CheckoutSCM' found among steps

with list of available methods below, where no mine CheckoutSCM for sure)

So, is there possible import class from src folder to Jenkinsfile?

P.S. I can access in Jenkinsfile MainDeploySteps as

MainDeploySteps {}

with no problems however.


Solution

  • I just wanted to add an answer to address a couple of questions from the OP and the subsequent comments.

    am I understand you correctly that shared library expose ONLY global vars from 'vars' directory, to include that vars to Jenkinsfile? While trying include anything else to Jenkinsfile directly from 'src' folder is not how it was designed, because 'src' classes intended to be include to vars from 'vars' directory.

    First let me give some background on shared libraries. There are 2 types referred to as dynamic shared library (defined using library step) and global shared library (defined in Jenkins global config and accessed using @Library annotation). Two important differences between these two are:

    Coming to the OP, it is using the dynamic shared library concept, which means, classes can't be referenced statically. However there are some features put into dynamic shared library that can be taken advantage of. These details can be found in the documentation, but here is a summary:

    In both types of libraries, var files are exposed using the same mechanism (referred to also as global vars and custom steps), so there is no difference in usage. Also, the var file executes in the context of the library so with in the var file, you do not need the special syntax to access the classes, whether they are in global or dynamic shared libraries.

    Now to answer the real question in the OP, it is possible to call CheckoutSCM from the dynamic shared library. If it is defined as a static function, it can be invoked using myLib.com.company.DeploySteps.CheckoutSCM('repo-here') and if it is defined as a non-static method, it can be invoked using myLib.com.company.DeploySteps.new(...).CheckoutSCM('repo-here'). However in both cases the DeploySteps class will not be able to access the steps API so even a simple echo will not work. One traditional workaround is to provide the this instance of Jenkinsfile as a parameter (e.g., CheckoutSCM(this, 'repo-here')) which then gets assigned to a steps parameter (can be named anything) inside the function. You would then invoke all step calls on the steps parameter, e.g., steps.echo '...'.