jenkins - 在 Jenkinsfile (Groovy) 中获取给定文件夹中的文件名列表
问题描述
我无法在脚本化的 Jenkins 流水线中的给定目录中创建简单的文件名列表。我尝试了许多在 SO 和其他论坛上发布的 Groovy 脚本示例,但要么该功能被阻止,要么我找不到方法或其他什么。
这似乎是最简单的
def DOCKER_FILES_DIR = './dockerfiles'
// ...
def dir = new File(DOCKER_FILES_DIR);
def dockerfiles = [];
dir.traverse(type: FILES, maxDepth: 0) {
dockerfiles.add(it)
}
但这会错误地解析相对路径,因此出现此错误:
java.io.FileNotFoundException: /./dockerfiles
我还尝试用以下方法包装它dir
:
def DOCKER_FILES_DIR = './dockerfiles'
// ...
def dockerfiles = [];
dir("${env.WORKSPACE}"){
def dir = new File(DOCKER_FILES_DIR);
dir.traverse(type: FILES, maxDepth: 0) {
dockerfiles.add(it)
}
}
但是得到了同样的错误:
java.io.FileNotFoundException: /./dockerfiles
这不会给出错误,但只会将一个文件添加到列表中:
def DOCKER_FILES_DIR = './dockerfiles'
// ...
def dockerfiles = [];
def dir = new File("${env.WORKSPACE}/${DOCKER_FILES_DIR}");
dir.traverse(type: FILES, maxDepth: 0) {
dockerfiles.add(it.getName())
}
的内容dockerfiles
然后丢失了除第一个文件之外的所有文件:
['py365']
这是在 Jenkins 中重现它的最小管道:
#!groovy
import static groovy.io.FileType.FILES
node('master') {
FILES_DIR = './foo'
cleanWs()
sh """
mkdir foo
touch foo/bar1
touch foo/bar2
touch foo/bar3
"""
def filenames = [];
def dir = new File("${env.WORKSPACE}/${FILES_DIR}");
dir.traverse(type: FILES, maxDepth: 0) {
filenames.add(it.getName())
}
for (int i = 0; i < filenames.size(); i++) {
def filename = filenames[i]
echo "${filename}"
}
}
输出,显示仅bar1
打印:
Started by user Tamas Gal
Running in Durability level: MAX_SURVIVABILITY
[Pipeline] node
Running on Jenkins in /var/lib/jenkins/workspace/TestHome
[Pipeline] {
[Pipeline] cleanWs
[WS-CLEANUP] Deleting project workspace...[WS-CLEANUP] done
[Pipeline] sh
[TestHome] Running shell script
+ mkdir foo
+ touch foo/bar1
+ touch foo/bar2
+ touch foo/bar3
[Pipeline] echo
bar1
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
Finished: SUCCESS
解决方案
您不能真正使用new File
常规的 Groovy/Java 方法来遍历文件系统。默认情况下,调用是经过安全检查的(请参阅JENKINS-38131),并且由于 Jenkins Pipelines 执行管道代码的方式,它甚至通常不会工作。
一种方法是使用Pipeline Utility Steps插件findFiles
中的步骤。它返回一个可以检查/用于其他目的的。FileWrapper[]
node {
// ... check out code, whatever
final foundFiles = findFiles(glob: 'dockerfiles/**/*')
// do things with FileWrapper[]
}
另一种选择是掏空并捕获标准输出:
node {
// ... check out code, whatever
final foundFiles = sh(script: 'ls -1 dockerfiles', returnStdout: true).split()
// Do stuff with filenames
}
推荐阅读
- reactjs - Reactjs 中的 auto prettier 打破了界限
- excel - VBA在两个数字之间找到带小数的数字
- python-3.x - 无法在不同用户的 python 3.6.2 中创建 MSI 或 exe?
- html - 可以使用锚点代替 div 容器吗?
- angular - 我想在 ngModuleFactory 中运行 moduleType 并将 name 属性值带入
- c# - C# 中 SQL 时间戳的数据类型是什么?
- db2 - 由于数据库,应用程序不断崩溃
- android - 如何编写具有重复部分的应用程序?
- eclipse - 如何在 Maven 中添加本地下载的原型?
- java - JavaFX,tableView在一列中缺少数据