41

I am trying to create a file called groovy1.txt with the content "Working with files the Groovy way is easy."

Note: I don't want to use the shell to create this file, instead I want to use Groovy to achieve this.

I have following script in my Jenkins pipeline.

node { def file1 = new File('groovy1.txt') file1.write 'Working with files the Groovy way is easy.\n' sh 'ls -l' // Expecting the file groovy1.txt should present with the content mentioned above } 

But it is throwing FileNotFound (permission denied) error as below

java.io.FileNotFoundException: groovy1.txt (Permission denied) at java.io.FileOutputStream.open0(Native Method) at java.io.FileOutputStream.open(FileOutputStream.java:270) at java.io.FileOutputStream.<init>(FileOutputStream.java:213) at java.io.FileOutputStream.<init>(FileOutputStream.java:162) at java.io.FileWriter.<init>(FileWriter.java:90) at org.codehaus.groovy.runtime.ResourceGroovyMethods.write(ResourceGroovyMethods.java:740) at org.codehaus.groovy.runtime.dgm$1035.doMethodInvoke(Unknown Source) at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1213) at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1022) at org.codehaus.groovy.runtime.callsite.PojoMetaClassSite.call(PojoMetaClassSite.java:47) at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113) at org.kohsuke.groovy.sandbox.impl.Checker$1.call(Checker.java:157) at org.kohsuke.groovy.sandbox.GroovyInterceptor.onMethodCall(GroovyInterceptor.java:23) at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.onMethodCall(SandboxInterceptor.java:104) at org.kohsuke.groovy.sandbox.impl.Checker$1.call(Checker.java:155) at org.kohsuke.groovy.sandbox.impl.Checker.checkedCall(Checker.java:159) at com.cloudbees.groovy.cps.sandbox.SandboxInvoker.methodCall(SandboxInvoker.java:17) at WorkflowScript.run(WorkflowScript:3) at ___cps.transform___(Native Method) at com.cloudbees.groovy.cps.impl.ContinuationGroup.methodCall(ContinuationGroup.java:57) at com.cloudbees.groovy.cps.impl.FunctionCallBlock$ContinuationImpl.dispatchOrArg(FunctionCallBlock.java:109) at com.cloudbees.groovy.cps.impl.FunctionCallBlock$ContinuationImpl.fixArg(FunctionCallBlock.java:82) at sun.reflect.GeneratedMethodAccessor257.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at com.cloudbees.groovy.cps.impl.ContinuationPtr$ContinuationImpl.receive(ContinuationPtr.java:72) at com.cloudbees.groovy.cps.impl.ConstantBlock.eval(ConstantBlock.java:21) at com.cloudbees.groovy.cps.Next.step(Next.java:83) at com.cloudbees.groovy.cps.Continuable$1.call(Continuable.java:174) at com.cloudbees.groovy.cps.Continuable$1.call(Continuable.java:163) at org.codehaus.groovy.runtime.GroovyCategorySupport$ThreadCategoryInfo.use(GroovyCategorySupport.java:122) at org.codehaus.groovy.runtime.GroovyCategorySupport.use(GroovyCategorySupport.java:261) at com.cloudbees.groovy.cps.Continuable.run0(Continuable.java:163) at org.jenkinsci.plugins.workflow.cps.SandboxContinuable.access$101(SandboxContinuable.java:34) at org.jenkinsci.plugins.workflow.cps.SandboxContinuable.lambda$run0$0(SandboxContinuable.java:59) at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.GroovySandbox.runInSandbox(GroovySandbox.java:108) at org.jenkinsci.plugins.workflow.cps.SandboxContinuable.run0(SandboxContinuable.java:58) at org.jenkinsci.plugins.workflow.cps.CpsThread.runNextChunk(CpsThread.java:174) at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.run(CpsThreadGroup.java:332) at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.access$200(CpsThreadGroup.java:83) at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup$2.call(CpsThreadGroup.java:244) at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup$2.call(CpsThreadGroup.java:232) at org.jenkinsci.plugins.workflow.cps.CpsVmExecutorService$2.call(CpsVmExecutorService.java:64) at java.util.concurrent.FutureTask.run(FutureTask.java:266) at hudson.remoting.SingleLaneExecutorService$1.run(SingleLaneExecutorService.java:131) at jenkins.util.ContextResettingExecutorService$1.run(ContextResettingExecutorService.java:28) at jenkins.security.ImpersonatingExecutorService$1.run(ImpersonatingExecutorService.java:59) at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) at java.util.concurrent.FutureTask.run(FutureTask.java:266) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) at java.lang.Thread.run(Thread.java:748) Finished: FAILURE 

1 Answer 1

81

Jenkins Pipeline provides writeFile step that can be used to write a file inside job's workspace.

Take a look at following example:

node { writeFile file: 'groovy1.txt', text: 'Working with files the Groovy way is easy.' sh 'ls -l groovy1.txt' sh 'cat groovy1.txt' } 

Running this pipeline scripts generates following output:

[Pipeline] node Running on Jenkins in /var/jenkins_home/workspace/test-pipeline [Pipeline] { [Pipeline] writeFile [Pipeline] sh [test-pipeline] Running shell script + ls -l groovy1.txt -rw-r--r-- 1 jenkins jenkins 42 Jul 8 16:38 groovy1.txt [Pipeline] sh [test-pipeline] Running shell script + cat groovy1.txt Working with files the Groovy way is easy.[Pipeline] } [Pipeline] // node [Pipeline] End of Pipeline Finished: SUCCESS 

Using Java File

As Jon S mentioned in the comment, Java new File("${env.WORKSPACE}/groovy1.txt") will work only if your node step is executed on master node - if it gets executed on slave node then your pipeline code will fail. You can check following Stack Overflow thread for more information:

In jenkins job, create file using system groovy in current workspace

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks a lot, very helpful.
This answer is particularly wrong, using Java standard file class will only work if the node step is allocated to the master, if it ends up on a slave, then standard file will fail... Reason for this is that all pipeline code is executed on the master, see stackoverflow.com/a/32514581/7509826 for more info. So use writeFile and it is guaranteed work!
THanks @JonS for your input! I haven't took it into account. Answer update to not confuse other people.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.