Use of "local" function in shared library

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

Use of "local" function in shared library

Adrian Wyssmann
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',
        remote: 'https://bitbucket.intra/scm/jenkins/pipeline-helper.git',
        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
 * Source: https://jenkins.io/blog/2017/10/02/pipeline-templates-with-shared-libraries/
 */
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.





--
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 [hidden email].
To view this discussion on the web visit https://groups.google.com/d/msgid/jenkinsci-users/014517de-e40a-48d6-9bbc-df2302f7ab6bn%40googlegroups.com.
Reply | Threaded
Open this post in threaded view
|

RE: Use of "local" function in shared library

Jérôme Godbout

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);

}

 

 

From: [hidden email] <[hidden email]> On Behalf Of Adrian Wyssmann
Sent: September 9, 2020 3:39 AM
To: Jenkins Users <[hidden email]>
Subject: Use of "local" function in shared library

 

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',

        remote: 'https://bitbucket.intra/scm/jenkins/pipeline-helper.git',

        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.

 

 

 

 

 

--
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 [hidden email].
To view this discussion on the web visit https://groups.google.com/d/msgid/jenkinsci-users/014517de-e40a-48d6-9bbc-df2302f7ab6bn%40googlegroups.com.

--
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 [hidden email].
To view this discussion on the web visit https://groups.google.com/d/msgid/jenkinsci-users/QB1PR01MB384482DB67F4B76D31CD3264CD260%40QB1PR01MB3844.CANPRD01.PROD.OUTLOOK.COM.
Reply | Threaded
Open this post in threaded view
|

RE: Use of "local" function in shared library

Jérôme Godbout

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);

}

 

 

From: [hidden email] <[hidden email]> On Behalf Of Adrian Wyssmann
Sent: September 9, 2020 3:39 AM
To: Jenkins Users <[hidden email]>
Subject: Use of "local" function in shared library

 

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',

        remote: 'https://bitbucket.intra/scm/jenkins/pipeline-helper.git',

        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.

 

 

 

 

 

--
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 [hidden email].
To view this discussion on the web visit https://groups.google.com/d/msgid/jenkinsci-users/014517de-e40a-48d6-9bbc-df2302f7ab6bn%40googlegroups.com.

--
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 [hidden email].
To view this discussion on the web visit https://groups.google.com/d/msgid/jenkinsci-users/QB1PR01MB384482DB67F4B76D31CD3264CD260%40QB1PR01MB3844.CANPRD01.PROD.OUTLOOK.COM.

--
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 [hidden email].
To view this discussion on the web visit https://groups.google.com/d/msgid/jenkinsci-users/QB1PR01MB384474B2CEA3C4B186CD8145CD260%40QB1PR01MB3844.CANPRD01.PROD.OUTLOOK.COM.