7

I am creating a jenkins pipeline job to seed jobs using the jenkins job DSL plugin. How do I get the workspace path inside the DSL file? The jenkins pipeline code is as such:

#!groovy
  node{
    stage("build jobs"){
      ws{
        git poll: true,  credentialsId: 'xxx', url: 'ssh://git@aaaaa.cc.xxx.com:/xxx/xxx.git'
        checkout scm
        jobDsl(removedJobAction: 'DISABLE', removedViewAction: 'DELETE', targets: 'jobs/*.groovy', unstableOnDeprecation: true)
      }
    }
  }

The DSL code that is failing is:

hudson.FilePath workspace = hudson.model.Executor.currentExecutor().getCurrentWorkspace()

With the error:

Processing DSL script pipeline.groovy
java.lang.NullPointerException: Cannot invoke method getCurrentWorkspace() on null object
    at org.codehaus.groovy.runtime.NullObject.invokeMethod(NullObject.java:91)
    at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.call(PogoMetaClassSite.java:48)
    at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48)
    at org.codehaus.groovy.runtime.callsite.NullCallSite.call(NullCallSite.java:35)
    at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:117)
    at pipeline.run(pipeline.groovy:1)
    at pipeline$run.call(Unknown Source)

Variables created in the pipeline area are not accessible inside the job DSL step

Stefan Crain
  • 2,010
  • 3
  • 21
  • 22
Graeme
  • 308
  • 1
  • 5
  • 15
  • Possible duplicate of [How to retrieve current workspace using Jenkins Pipeline Groovy script?](http://stackoverflow.com/questions/37846028/how-to-retrieve-current-workspace-using-jenkins-pipeline-groovy-script) – StephenKing Jan 12 '17 at 11:04
  • Possible duplicate of [Get absolute path to workspace directory in Jenkins Pipeline plugin](http://stackoverflow.com/questions/36934028/get-absolute-path-to-workspace-directory-in-jenkins-pipeline-plugin) – Jan Fabry Mar 31 '17 at 09:48

4 Answers4

5

I stumbled upon this because there seems to be no good way. Here is how I do it:

node {
    stage('test') {
        sh 'pwd > workspace.txt'
        jobDsl scriptText: '''
            String workspace = readFileFromWorkspace('workspace.txt').trim()
            def file = new File(workspace, 'test.txt')
            file.append('It worked!')'''
    }
}

So first grab the workspace in the pipeline script and then pass it to the job dsl. If you have more than just the workspace variable, that you need in your scripts I suggest transferring via a properties file:

node {
    stage('test') {
        sh 'echo "workspace="$(pwd) > build.properties'
        jobDsl scriptText: '''
            Properties props = new Properties();
            props.load(streamFileFromWorkspace('build.properties'))
            def file = new File(props.getProperty('workspace'), 'test.txt')
            file.append('It worked!')'''
    }
}
Peter Lutz
  • 165
  • 5
  • 9
4

This can be achieved by using SEED_JOB variable:

 String workspacePath = SEED_JOB.lastBuild.checkouts[0].workspace

It is described in project's wiki:

Access to the seed job is available through the SEED_JOB variable. The variable contains a reference to the internal Jenkins object that represents the seed job. The actual type of the object depends on the type of job that runs the DSL. For a freestyle project, the object is an instance of hudson.model.FreeStyleProject. See the Jenkins API Documentation for details.

The SEED_JOB variable is only available in scripts, not in any classes used by a script. And it is only available when running in Jenkins, e.g. in the "Process Job DSLs" build step.

The following example show how to apply the same quiet period for a generated job as for the seed job.

job('example') { quietPeriod(SEED_JOB.quietPeriod) }

Yuri G.
  • 86
  • 1
  • 5
  • The answer should be modified to use `SEED_JOB.getWorkspace()`. That seems the more elegant solution that worked fo rme. – chizou Feb 13 '19 at 07:55
  • 1
    I get the following error on `SEED_JOB.getWorkspace()`: "No signature of method: org.jenkinsci.plugins.workflow.job.WorkflowJob.getWorkspace() is applicable for argument types: () values: []". I guess it depends on the class (as noted in the cited wiki section) used for a seed job. E.g. `hudson.model.FreeStyleProject` does have `getWorkspace` method. – Yuri G. Feb 15 '19 at 13:47
3

You can use the __FILE__ variable in a Job DSL script to get the path of the current script. Maybe you can use that to derive the workspace directory. See Script Location for details.

def scriptDir = new File(__FILE__).parent.absolutePath
daspilker
  • 8,154
  • 1
  • 35
  • 49
  • Thanks that got me going in the right direction but it does have the limitation of only being able to use the master node. unfortunately building on the master is not allowed in the organisation i work for. – Graeme Jan 17 '17 at 06:24
  • You should open a new question describing the problem you want to solve. Getting the path only seems to be a part of the puzzle. Maybe there is another solution. – daspilker Jan 17 '17 at 07:49
  • i shall do that – Graeme Feb 02 '17 at 06:01
1

You can pass the workspace argument to job dsl. for example:

The pipeline code as follow:

node {
    step([
        $class: 'ExecuteDslScripts',
        scriptText: 'job("example-2")'
    ])
    step([
        $class: 'ExecuteDslScripts',
        targets: ['jobs/projectA/*.groovy', 'jobs/common.groovy'].join('\n'),
        removedJobAction: 'DELETE',
        removedViewAction: 'DELETE',
        lookupStrategy: 'SEED_JOB',
        additionalClasspath: ['libA.jar', 'libB.jar'].join('\n'),
        additionalParameters: [
            message: 'Hello from pipeline',
            credentials: 'SECRET'
            WORKSPACE: env.WORKSPACE
        ]
    ])
}

https://github.com/jenkinsci/job-dsl-plugin/wiki/User-Power-Moves#use-job-dsl-in-pipeline-scripts

Jian
  • 9
  • 1