Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Upload file in Jenkins input step to workspace

I would like to use the "input step" of Jenkins to upload a binary file to the current workspace.

However, the code below seems to upload the file to the Jenkins master, not to the workspace of the current job on the slave where the job is running. Is there any way to fix that?

Preferably without having to add an executor on the master or clutter the master disk with files.

def inFile = input id: 'file1', message: 'Upload a file', parameters: [file(name: 'data.tmp', description: 'Choose a file')]
like image 407
Timmy Brolin Avatar asked Aug 12 '19 15:08

Timmy Brolin


1 Answers

Seems Jenkins officially doesn't support upload of binary file yet as you can see in JENKINS-27413. You can still make use of the input step to get binary file in your workspace. We will be using a method to get this working but we will not use it inside the Jenkinsfile otherwise we will encounter errors related to In-process Script Approval. Instead, we will use Global Shared Libraries, which is considered one of Jenkins' best practices.

Please follow these steps:

1) Create a shared library

  • Create a repository test-shared-library
  • Create a directory named vars in above repository. Inside vars directory, create a file copy_bin_to_wksp.groovy with the following content:

def inputGetFile(String savedfile = null) {
    def filedata = null
    def filename = null
    // Get file using input step, will put it in build directory
    // the filename will not be included in the upload data, so optionally allow it to be specified

    if (savedfile == null) {
        def inputFile = input message: 'Upload file', parameters: [file(name: 'library_data_upload'), string(name: 'filename', defaultValue: 'demo-backend-1.0-SNAPSHOT.jar')]
        filedata = inputFile['library_data_upload']
        filename = inputFile['filename']
    } else {
        def inputFile = input message: 'Upload file', parameters: [file(name: 'library_data_upload')]
        filedata = inputFile
        filename = savedfile
    }

    // Read contents and write to workspace
    writeFile(file: filename, encoding: 'Base64', text: filedata.read().getBytes().encodeBase64().toString())
    // Remove the file from the master to avoid stuff like secret leakage
    filedata.delete()
    return filename
}

2) Configure Jenkins for accessing Shared Library in any pipeline job

  • Go to Manage Jenkins » Configure System » Global Pipeline Libraries section
  • Name the library whatever you want (in my case, my-shared-library as shown below)
  • Keep the default to master (this is the branch where i pushed my code)
  • No need to check/uncheck the check-boxes unless you know what you're doing

enter image description here

3) Access shared library in your job

  • In Jenkinsfile, add the following code:

@Library('my-shared-library@master') _

node {
   // Use any file name in place of *demo-backend-1.0-SNAPSHOT.jar* that i have used below
   def file_in_workspace = copy_bin_to_wksp.inputGetFile('demo-backend-1.0-SNAPSHOT.jar')
   sh "ls -ltR"
}

enter image description here

You're all set to run the job. :)

enter image description here

Note:

  • Make sure Script Security plugin is always up-to-date
  • How are Shared Libraries affected by Script Security?
  • Global Shared Libraries always run outside the sandbox. These libraries are considered "trusted:" they can run any methods in Java, Groovy, Jenkins internal APIs, Jenkins plugins, or third-party libraries. This allows you to define libraries which encapsulate individually unsafe APIs in a higher-level wrapper safe for use from any Pipeline. Beware that anyone able to push commits to this SCM repository could obtain unlimited access to Jenkins.
  • Folder-level Shared Libraries always run inside the sandbox. Folder-based libraries are not considered "trusted:" they run in the Groovy sandbox just like typical Pipelines.

Code Reference: James Hogarth's comment

like image 170
Technext Avatar answered Sep 24 '22 23:09

Technext