我无法在脚本化的Jenkins管道中的给定目录中创建简单的文件名列表。我尝试在SO和其他论坛上发布了很多Groovy Script示例,但要么功能被阻止,要么我找不到方法或其他什么。
这似乎是最简单的
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
答案 0 :(得分:13)
您无法真正使用new File
和普通的Groovy / Java方法来遍历文件系统。默认情况下,调用是安全检查的(参见JENKINS-38131),由于Jenkins Pipelines如何执行管道代码,因此通常无法正常工作。
您可以这样做的一种方法是使用findFiles
中的Pipeline Utility Steps plugin步骤。它返回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
}
答案 1 :(得分:3)
这个有用,但它很丑陋地说:
#!groovy
node('master') {
FILES_DIR = './foo'
cleanWs()
sh """
mkdir foo
touch foo/bar1
touch foo/bar2
touch foo/bar3
"""
def TMP_FILENAME = ".docker_files_list"
sh "ls ${FILES_DIR} > ${TMP_FILENAME}"
def filenames = readFile(TMP_FILENAME).split( "\\r?\\n" );
sh "rm -f ${TMP_FILENAME}"
for (int i = 0; i < filenames.size(); i++) {
def filename = filenames[i]
echo "${filename}"
}
}