15

We have a series of Jenkinsfile scripts which are identical, except each configures an environment item to point to the directory in the SCM checkout that holds the Jenkinsfile. That is used to reference a file in the same directory. The SCM repo has all of these Jenkinsfile scripts in different directories. I see an easy opening to make the pipeline script identical in each case if I could only retrieve the path of the directory containing the Jenkinsfile.

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
  • 2,520
  • 4
  • 36
  • 55
  • Always keep your Jenkinsfile at the root of your directory. Then use 'branch' conditions (when { branch 'develop' }) to get your configuration per environment. – sridesmet Aug 21 '18 at 13:48
  • 1
    That doesn't work. One SCM repo contains numerous independent pipelines. I'm not going to fracture the repo into 100 different ones just so I can get an identical Jenkinsfiles in each case. It is really surprising that Jenkins Pipeline doesn't give simple access to this information. – Kevin Buchs Aug 21 '18 at 21:11
  • sparse checkout? – sridesmet Aug 22 '18 at 07:54
  • 1
    @KevinBuchs I'm in the same situation. Did the find a solution to you question? – keda Jan 31 '19 at 18:50
  • @keda - no. I hope to get back to this, because there must be a way to do it, but I have to dig into the Java objects, etc. – Kevin Buchs Feb 01 '19 at 19:26

3 Answers3

6

Found at another thread:

def currentScriptPath = new File(currentBuild.rawBuild.parent.definition.scriptPath).parent

But it requires to approve a lot of methods.

MagMax
  • 1,645
  • 2
  • 17
  • 26
  • This is the only one that works in latest Jenkins in both shared pipeline libs and in Jenkinsfiles themselves, thanks! – daniilyar Apr 26 '20 at 10:57
  • Unfortunately this method only works in the actual node context— you can't use it at the top of the Jenkinsfile to determine, for example, where to get a pod definition for kubernetes { yamlFile }. – mikepurvis Apr 08 '21 at 19:08
  • This doesn't give me a path but only the file name (when used minus the File and parent parts, otherwise null) – kjyv Mar 02 '22 at 15:17
1

If you really need this, you can fetch "${JOB_URL}config.xml" and parse scriptPath.

But that's not a clean solution and the request needs to be authenticated.

Chadi
  • 737
  • 1
  • 6
  • 21
  • This looks promising. I can see the job config is properly referenced via JOB_URL. I can see the ScriptPath in the Config when viewing from an authenticated browser session. I can't http get the file from a Pipeline script, because we have authentication on our Jenkins. I don't know how to get that file from within the Pipeline groovy script. I need to determine how get at that information another way. Given the job configuration data structure, I have to believe that that information must be loaded into the JVM in memory, and with loading the right objects in Groovy, I can get at this. – Kevin Buchs Sep 04 '18 at 22:27
-2

The simplest way is to put the Jenkinsfile at the root of your repository and get the value of the WORKSPACE environment variable set by Jenkins.

Given that Groovy is just basically Java, you can get the absolute path like so:

new File("{env.WORKSPACE}").absolutePath
Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
Andrew Gray
  • 3,593
  • 3
  • 35
  • 62
  • 2
    Not in my case. We have one SCM repo with numerous Jenkinsfiles in different directories. The location of the Jenkinsfile is given when the Jenkins pipeline is created. – Kevin Buchs Aug 19 '18 at 01:56
  • I would suggest restructuring your setup if you can. – Andrew Gray Aug 19 '18 at 01:59
  • @KevinBuchs how is the location given to Jenkins ?? – rohit thomas Aug 20 '18 at 03:00
  • When a pipeline job is created, with the script (Jenkinsfile) coming from SCM, you specify the script path as part of the job configuration. Screen shot: https://1drv.ms/u/s!AgKA2HL-SveIgYJEJIfTqbccHIBFFw – Kevin Buchs Aug 20 '18 at 21:03
  • Highly recommend making life easier for yourself and just specify Jenkinsfile without the path and then you can get the absolute path by accessing the environment variable Jenkins sets for all job {env.WORKSPACE}. – Andrew Gray Aug 21 '18 at 08:44
  • Not sure why you would need to do that cause all paths in the context of a running job are already all WORKSPACE relative. – Andrew Gray Aug 21 '18 at 08:45
  • The paths to the Jenkinsfiles are certainly relative to workspace. That doesn't mean the path is known to the pipeline Groovy code. – Kevin Buchs Aug 21 '18 at 21:13
  • This answer is [being discussed on meta](https://meta.stackoverflow.com/q/372952/5211833). – Adriaan Aug 23 '18 at 11:43