6

I am one short step away from being able to replace numerous customized Jenkinsfiles with one. All I need to get is the directory containing the Jenkinsfile under execution. I am using the Declarative pipeline syntax.

I looked at several ideas in groovy code, but could not find how to obtain this.

For those that need to see something specific, a Jenkinsfile looks like this at the top:

#!/usr/bin/env groovy
pipeline {
  agent any
  environment {
    tf='/var/lib/jenkins/tools/terraform0108/terraform'
    dir='clients/xyz/us-east-1/dev'
}

That variable dir is assigned to the location of that Jenkinsfile. dir is accessed later in the groovy code. I want to be able to omit that assignment and just pick up that directory from context of the executing script.

I tried several different things like steps containing

script {
    println __FILE__
}

and

script { 
    scriptDir = new File(getClass().protectionDomain.codeSource.location.path).parent
    println scriptDir
}

Neither of which ran (gave non-existent variable in FILE case and permission violation in the second case). I tried "${FILE}" and other variants.

I need to use the directory in a steps -- sh block so I believe it needs to be in an environment item.

Now, the Jenkins job configuration gives the path to the Jenkins file, but I don't want to have to repeat that to create another environment variable at that level.

Already consulted:

Help is appreciated.

Kevin Buchs
  • 353
  • 1
  • 3
  • 20

3 Answers3

2

There are lots of ways to do this. Here are two ways I can think of off the top of my head:

steps {
  println(WORKSPACE)
}

or

steps {
  def foo = sh(script: 'pwd', returnStdout: true)
  println(foo)
}
jayhendren
  • 1,014
  • 5
  • 12
  • 4
    Ah, I bet you are assuming my Jenkinsfile will be at the top of the workspace. It is located down into subdirectories. Using WORKSPACE or pwd only give the Workspace directory for the job, not the location of the Jenkinsfile it is executing. – Kevin Buchs Aug 15 '18 at 14:18
1

In my MultiBranchPipeline I've achieved the goal using this shared library code:

#!groovy
import jenkins.model.Jenkins

String call() {
    String thisMultiBranchProjectName = JOB_NAME.split('/')[0]
    def thisMultiBranchProject = Jenkins.getInstance().getItemByFullName(thisMultiBranchProjectName)
    def thisBranchProjectFactory = thisMultiBranchProject.getProjectFactory()
    String thisStringPath = thisBranchProjectFactory.getScriptPath()

    return thisStringPath
}

I do concede that this looks more like a hack…

kgadek
  • 111
  • 3
0

You're asking about pipelines, not JobDSL, but hopefully this helps/applies:

In my DSL seed jobs I use:

// Boilerplate
def dslWorkspacePath = new File(__FILE__).parent
evaluate(new File("${dslWorkspacePath}/scaffolding.groovy"))

in order to determine the path of the seed job that is currently being processed by JobDSL and then run some setup code.

My seed jobs do not sit in the root of the repo that gets cloned, but rather something like /src/main/groovy/jobdsl/

Denham Coote
  • 101
  • 1
  • Thanks for trying! I can easily get the Workspace directory. However, Pipeline allows you to reference a Jenkinsfile with a path (it is not at the top of the workspace) in the setup. I need that path. – Kevin Buchs Feb 11 '19 at 16:49
  • Sorry, should have checked that. `__FILE__` returns groovy.lang.MissingPropertyException: No such property: `__FILE__` for class. Keep in mind that what you see in the config is where it's been configured to pull from SCM, not where it lives once it's been pulled. That's usually something like jobname@script folder. (I'm sure you know this already) – Denham Coote Feb 12 '19 at 09:54
  • 1
    Also, consider that there may not always be a path to the running script (ie, when it's entered directly into the job config, not pulled from scm) – Denham Coote Feb 12 '19 at 10:09