带有文件参数的Jenkins管道作业
我正在准备一个Jenkins管道作业,它将接受一个文件参数。我可以触发作业并将其指向一个文件,但我找不到文件的结尾(在普通自由式作业中,它将位于工作区中)带有文件参数的Jenkins管道作业,jenkins,parameters,jenkins-pipeline,Jenkins,Parameters,Jenkins Pipeline,我正在准备一个Jenkins管道作业,它将接受一个文件参数。我可以触发作业并将其指向一个文件,但我找不到文件的结尾(在普通自由式作业中,它将位于工作区中) 上传的文件到哪里去了?或者文件参数当前不适用于管道 管道和文件参数当前存在问题 ()。解决方法如下: node { deleteDir() stage("upload") { def inputFile = input message: 'Upload file', parameters: [file(name
上传的文件到哪里去了?或者文件参数当前不适用于管道 管道和文件参数当前存在问题
()。解决方法如下:
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()
}
}
我知道这个解决方案并没有那么漂亮,因为上传过程中管道会被中断,但它可以工作
此外,“copyFrom”是必要的,因为输入将“data.zip”存储在jobs目录中,而不是工作区中(不知道为什么)我尝试使用@Christoph Forster提供的解决方案,但输入文件没有被复制到工作区的任何地方。 因此,我使用了中提供的变通方法 该库提供了一个新库unstashParam,用于将文件构建参数保存到工作区中。可用于文本和yaml文件。找到WA(严格用于基于文本的文件输入) 我们可以使用Jenkins多行字符串参数并要求用户将文件内容粘贴到其中。 在我们的管道中,使用管道步骤writeFile写入此参数的内容,如下所示:
stage('File Param WA') {
writeFile file: 'demo.yaml', text: params.DEMO_YAML
}
我还尝试使用@Christoph Forster提供的解决方案,但在启用Groovy Sandbox时收到一个脚本安全错误
org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException: Scripts not permitted to use new hudson.FilePath java.io.File
但是,我们似乎可以跳过文件复制和删除操作(并绕过Groovy沙盒限制),只需将文件上载到作业工作区即可。只需将workspace变量添加到文件名,如下所示:
stage("upload") {
def inputFile = input message: 'Upload file', parameters: [file(name: "$workspace/data.zip")]
}
我在这里找到了一个全局库形式的解决方案: 它包含对Jenkins的内部方法的调用,我猜这些方法已经被弃用了。 所以我自己做了这样的版本:
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"
}
您可以将其插入全局库中,然后按如下方式使用:
library "file-workaround"
node {
def file_in_workspace = unstashParam "myFile"
sh "cat ${file_in_workspace}"
}
这并不漂亮,但它的工作,只要没有正式的修复,这是我最好的拍摄
更新事实证明,您可能会遇到“没有这样的文件或目录”。这是因为解决方案中没有任何内容会触发Jenkins创建工作区目录。如果这是在管道中的其他地方触发的,那么很好,否则你会抓狂的。
你可能想扔个球
touch "thisIsAFile"
在那里尝试了克里斯托夫的建议,但对我不起作用。这是我的工作和设置,我有,他的应该帮助别人知道该怎么做 问题: 我在专用节点上执行管道,并使用经过清理的工作区。经过一些研究和故障排除,我发现默认情况下,文件上载只适用于主节点。我在挖掘文件系统并在master上的工作区中找到我正在上传的文件后意识到了这一点 解决方案:
stage('Upload Key') {
agent { label 'master' }
steps {
script {
// Uploads file via master node and stases it for other nodes to access
def inputFile = input message: 'Upload file', parameters: [file(name: "key.p12")]
new hudson.FilePath(new File("${workspace}/key.p12")).copyFrom(inputFile)
inputFile.delete()
}
stash name: 'key.p12' , includes: "key.p12"
}
}
stage('Register') {
steps {
ws (sanitizedWorkspaceName) {
echo "Registering"
unstash 'key.p12'
}
}
}
希望这有助于处理管道中的可选文件参数(处理不应接受任何文件的用例)。您可以使用jenkinsci unstashParam库(在Jenkins>Manage Jenkins>Configure System>Global pipeline Libraries中添加它),并在脚本中使用try/catch作为此示例阶段:
stage('upload') {
steps {
// delete workspace
cleanWs()
// handle file parameters in pipeline (JENKINS-27413)
script {
try {
// force workspace directory creation
sh "touch emptyFileToCreateWorkspace"
// https://stackoverflow.com/questions/59468464/fetching-uploaded-files-in-jenkins
def file_in_workspace = unstashParam 'MY_FILE.xlsx'
// https://unix.stackexchange.com/questions/125776/error-with-a-file-name-containing-parentheses
sh "mv '${file_in_workspace}' MY_FILE.xlsx"
}
catch (Exception e) {
echo e.getMessage()
echo "No file parameter, we will continue.."
}
}
}
}
如果文件上载到主节点,而需要从节点,则我无法使Christoph的解决方案工作。解决办法是把它藏在主机上,然后把它从主机上取下来。不要忘记删除主节点上上载的文件。
java.nio.file.NoSuchFileException:jenkins/workspace/job/data.zip
我遇到了另一个问题:脚本不允许使用新的java.io.file java.lang.String
您需要首先允许这些方法。可以在这里完成,但无法可靠地使用此解决方法--文件不会随机复制到工作区。java.io.FileNotFoundException:/var/lib/jenkins/workspaces/some project/data.zip(没有这样的文件或目录)
我在jenkins主服务器上找到了该文件(不在workers/executors上)在这个路径上:/var/lib/jenkins/jobs/$JOB\u NAME/builds/$BUILD\u NUMBER/example.txt注意,我没有在def inputFile=input message中指定完整路径:“Upload file”,参数:[file(NAME:“example.txt”)]对我来说非常有用。脚本将在上载步骤暂停,直到您转到批准并上载文件。神奇而简单!