-1

Here's a simple Jenkins pipeline job that highlights the different working directories seen by sh vs script.

pipeline {
  agent any

  stages {
    stage('Stage1') {
      steps {
        sh """
        pwd
        """
        script {
          echo "cwd--pwd: "+ "pwd".execute().text
        }
      }
    }
  }
}

Here's how the Jenkins instance was launched

/Users/MyJenkinsUser/dirJenkinsLaunched$ java -jar /Applications/Jenkins/jenkins.war --httpPort=8080

Here's the console output of the job...

Started by user MyJenkinsUser
Running in Durability level: MAX_SURVIVABILITY
[Pipeline] node
Running on Jenkins in /Users/MyJenkinsUser/.jenkins/jobs/TestPipeline/workspace
[Pipeline] {
[Pipeline] withEnv
[Pipeline] {
[Pipeline] stage
[Pipeline] { (Stage1)
[Pipeline] sh
[workspace] Running shell script
+ pwd
/Users/MyJenkinsUser/.jenkins/jobs/TestPipeline/workspace
[Pipeline] script
[Pipeline] {
[Pipeline] echo
cwd--pwd: /Users/MyJenkinsUser/dirJenkinsLaunched
[Pipeline] }
[Pipeline] // script
[Pipeline] }
[Pipeline] // stage
[Pipeline] }
[Pipeline] // withEnv
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
Finished: SUCCESS

I find it curious that they would be different working directories, the shell command sh step uses the workspace as the working directory while the groovy script step uses the directory the Jenkins process was launched.

Question: how can I make my Jenkins scripted pipeline steps (script) use the workspace as the working directory by default?


I guess it makes sense after realizing this most clearly, that groovy is a java thing and we launch the Jenkins war file from java, and that launching imposes a certain working directory. I wonder the origins of this design for the Jenkins behavior. It made me go a bit wonky with a bunch of file not found errors as I ported some sh commands into the more substantive groovy syntax because I wanted to avoid all the double nesting escaping craziness that one can fall into in the shell, especially when spaces are invoked in paths and what not.

jxramos
  • 7,356
  • 6
  • 57
  • 105

2 Answers2

1

You shall not use execute() in Jenkins pipelines. Use the pipeline DSL's steps instead of arbitrary Groovy code.

As you noticed, this such "native" code is executed on the Jenkins master and without any relation to the current job.

StephenKing
  • 36,187
  • 11
  • 83
  • 112
  • Wow, that’s a subtlety that would not come out till late using the strategy I was on to prototype a pipeline via the `Pipeline > Definition > Pipeline script` on master before submitting to a Jenkinsfile in source control that targets a labeled node. In my circumstance it just so happens that the user name for both machines is identical which would have obscured things further. I think the [docs](https://jenkins.io/doc/book/pipeline/syntax/#script) would benefit greatly if they bothered to make this huge distinction very explicit. – jxramos Sep 24 '18 at 16:01
0

Unfortunately this may not be a possible operation. I'll have to redesign the script code to explicitly use the workspace variable instead of relying on the current working directory Java uses.

Changing the current working directory in Java?

jxramos
  • 7,356
  • 6
  • 57
  • 105