Jenkins Pipeline Job with file parameter

流过昼夜 提交于 2019-11-27 01:48:01

问题


I'm putting together a Jenkins pipeline job which will take a file parameter. I can trigger the job and point it at a file however I can't find where the file has ended up (In an ordinary freestyle job it would be in the workspace).

Where has the uploaded file gone? Or do file parameters not currently work with pipelines?


回答1:


There is currently an issue with pipeline and file parameter (https://issues.jenkins-ci.org/browse/JENKINS-27413).




回答2:


Solved it the following way:

node {
    deleteDir()
    stage("upload") {
        def inputFile = input message: 'Upload file', parameters: [file(name: 'data.zip')]
        new hudson.FilePath(new File("$workspace/data.zip")).copyFrom(inputFile)
        inputFile.delete()
    }
    stage("checkout") {
        echo fileExists('data.zip').toString()
    }
}

I know the solution is not that beautiful because the pipeline gets interrupted for the upload but it works.

Further the "copyFrom" is necessary, because the input stores the "data.zip" in the jobs directory and not in the workspace (don't know why)




回答3:


Found a WA (Strictly for text based file input) We can use Jenkins multi-line string parameter and ask user to paste file contents to it. And in our pipeline, write contents of this parameter using pipeline step writeFile, as :

stage('File Param WA') {
          writeFile file: 'demo.yaml', text: params.DEMO_YAML
}




回答4:


I tried using the solution provided by @Christoph Forster , but the input File was not getting copied anywhere in the workspace . So I used the workaround as provided in https://bitbucket.org/janvrany/jenkins-27413-workaround-library/src/6b7dada8ea37?at=default

The library provides a new library - unstashParam - that saves the file build parameter into a workspace. Works fine with text and yaml file .




回答5:


I found a solution in the form of a global library here: https://bitbucket.org/janvrany/jenkins-27413-workaround-library/src/default/

It contains calls to inner methods of Jenkins which are deprecated (I guess). So I made my own version like this:

import hudson.FilePath
import hudson.model.ParametersAction
import hudson.model.FileParameterValue
import hudson.model.Executor

def call(String name, String fname = null) {
    def paramsAction = currentBuild.rawBuild.getAction(ParametersAction.class);

    if (paramsAction == null) {
        error "unstashParam: No file parameter named '${name}'"
    }

    for (param in paramsAction.getParameters()) {
        if (param.getName().equals(name)) {
            if (! param instanceof FileParameterValue) {
                error "unstashParam: not a file parameter: ${name}"
            }
            if (env['NODE_NAME'] == null) {
                error "unstashParam: no node in current context"
            }
            if (env['WORKSPACE'] == null) {
                error "unstashParam: no workspace in current context"
            }
            workspace = new FilePath(getComputer(env['NODE_NAME']), env['WORKSPACE'])
            filename = fname == null ? param.getOriginalFileName() : fname
            file = workspace.child(filename)
            file.copyFrom(param.getFile())
            return filename;
        }
    }
}


def getComputer(name){

    for(computer in Jenkins.getInstance().getComputers()){ 
        if(computer.getDisplayName() == name){
            return computer.getChannel()
        }
    }

    error "Cannot find computer for file parameter workaround"
}

You can insert it in a global library and then use it like:

library "file-workaround"

node {
    def file_in_workspace = unstashParam "myFile"
    sh "cat ${file_in_workspace}"
}

It's not pretty but it's working and as long as there is no official fix, it's my best shot.

Update
Turns out you might run into "No such file or directory". That's because nothing in the workaround triggers Jenkins to create the workspace directory. If that was triggered somewhere else in the pipeline good, otherwise you'll be scratching your head.
You might wanna throw a

touch "thisIsAFile"

in there




回答6:


I also tried using the solution by @Christoph Forster but I received a script security error when Groovy Sandbox is enable

org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException: Scripts not permitted to use new hudson.FilePath java.io.File

However, it seems we can skip the file copying and deleting actions (and bypass the Groovy sandbox restriction) by simply requiring that the file is uploaded to the job workspace. Just add the workspace variable to the file name as follows:

stage("upload") {
def inputFile = input message: 'Upload file', parameters: [file(name: "$workspace/data.zip")]
        }


来源:https://stackoverflow.com/questions/38080876/jenkins-pipeline-job-with-file-parameter

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!