Jenkins – can not create file via Groovy code(or java code) in jenkinsfile of a pipeline job on Jenkins

groovyJenkinsjenkins-pipeline

pipeline {
    agent any

    stages {
        stage('Build') {
            steps {
                echo 'Building..'
                echo "whoami".execute().text
                script {
                    File f = new File('/home/jenkins/test2.txt');
                    f.createNewFile();
                }
            }
        }
        stage('Test') {
            steps {
                echo 'Testing..'
            }
        }
        stage('Deploy') {
            steps {
                echo 'Deploying....'
            }
        }
    }
}

Jenkins console log: (got exception: Started by user Edgar Yu Running
in Durability level: MAX_SURVIVABILITY [Pipeline] node Running on
Jenkins in /var/jenkins_home/workspace/test2 [Pipeline] { [Pipeline]
stage [Pipeline] { (Build) [Pipeline] echo Building.. [Pipeline] echo
jenkins

[Pipeline] script [Pipeline] { [Pipeline] } [Pipeline] // script
[Pipeline] } [Pipeline] // stage [Pipeline] stage [Pipeline] { (Test)
Stage 'Test' skipped due to earlier failure(s) [Pipeline] } [Pipeline]
// stage [Pipeline] stage [Pipeline] { (Deploy) Stage 'Deploy' skipped
due to earlier failure(s) [Pipeline] } [Pipeline] // stage [Pipeline]
} [Pipeline] // node [Pipeline] End of Pipeline
java.io.IOException: Permission denied at java.io.UnixFileSystem.createFileExclusively(Native Method) at
java.io.File.createNewFile(File.java:1012)

Best Answer

This is due to Jenkins not implementing Groovy itself but an interpreter (CPS) - https://github.com/cloudbees/groovy-cps

To help deal with the complexities introduced, there are some common Steps implemented to take the trouble out of tasks such as creating a file.

To use Jenkins pipeline steps out of the box, use writeFile: https://jenkins.io/doc/pipeline/steps/workflow-basic-steps/#code-writefile-code-write-file-to-workspace

writeFile([file: 'file.txt', text: filetxt])

If your deadset on writing your own, I suggest splitting it out into a Shared library, note this will probably cause ScriptSecurity alerts that will require approval:

final class PipelineUtils implements Serializable {
    private script=null
    private static final PipelineUtils instance = new PipelineUtils()
    @NonCPS
    String saveFile(String filename, String text) {
        String PWD = script.pwd()
        String filePath = "${PWD}/${filename}"

        File file = new File(filePath)
        file.text = text
    }
}

See https://github.com/jenkinsci/pipeline-plugin/blob/master/TUTORIAL.md for information regarding @NonCPS and nonserializable objects.