Use of "local" function in shared library

23 views
Skip to first unread message

Adrian Wyssmann

unread,
Sep 9, 2020, 3:38:50 AM9/9/20
to Jenkins Users
I use a shared library for our projects to have a common ci pipeline. There are still some project specific stuff like the build script. So what I would like to do is defined some functions in the local project's Jenkinsfile and use them in the library

So here is my Jenkinsfile
library identifier: "pipeline-helper@master", retriever: modernSCM(
    [$class: 'GitSCMSource',
        credentialsId: 'bitbucket.service.user'
    ])

defaultCiPipelineGeneric {
    node = "APR"
}

/**
 * Builds the application based on parameters
 * @param pipelineParams map of all pipeline parameters
 */
def buildApplication(pipelineParams) {
    powershell '''
Write-Host "### [INFO] $(Get-Date) Restoring nuget packages: ${env:NUGET_HOME}"

$exe = ${env:NUGET_HOME} + "\\nuget.exe"
&$exe restore .\\Solution.sln
cmd.exe /c .\\Build.bat
cmd.exe /c .\\UnitTests.bat
'''
}

The pipeline-helper defined the common pipeline, where I would like to use buildApplication(). 

in the defaultCiPipelineGeneric.groovy
/**
 * Shared ci pipeline for maven projects
 */
def call(body) {
    // evaluate the body block, and collect configuration into the object
    def pipelineParams= [:]
    body.resolveStrategy = Closure.DELEGATE_FIRST
    body.delegate = pipelineParams
    body()

    pipeline {
        agent {
            label pipelineParams.nodes
        }
        stages {
            stage('Build') {
                steps {
                    script {
                        buildApplication(pipelineParams)
                    }
                }
            }
        }
    }
}

However this does not work as I get the following error


Is this even possible? I know that I could have a separate groovy file and load int with the load-function. But I find it more appealing when you only have to have one file (Jenkinsfile) which contains all instruction for building.





Jérôme Godbout

unread,
Sep 9, 2020, 9:40:46 AM9/9/20
to jenkins...@googlegroups.com

Out of curiosity, why don’t you pass the function as a argument to your call block? You could pass a functor there that will be reuse, so you do not need any env var or weird scope. This would give something like this to your call:

 

defaultCiPipelineGeneric({ // previous stuff of body goes here}, buildApplication);

 

and your call could be something like this

def call(body, buildFct) {

buildApplication(pipelineParams);

--
You received this message because you are subscribed to the Google Groups "Jenkins Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to jenkinsci-use...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/jenkinsci-users/014517de-e40a-48d6-9bbc-df2302f7ab6bn%40googlegroups.com.

Jérôme Godbout

unread,
Sep 9, 2020, 9:41:42 AM9/9/20
to jenkins...@googlegroups.com

My bad typo:

 

Out of curiosity, why don’t you pass the function as a argument to your call block? You could pass a functor there that will be reuse, so you do not need any env var or weird scope. This would give something like this to your call:

 

defaultCiPipelineGeneric({ // previous stuff of body goes here}, buildApplication);

 

and your call could be something like this

def call(body, buildFct) {

buildFct(pipelineParams);

Reply all
Reply to author
Forward
0 new messages