I cannot create a simple list of filenames in a given directory in a scripted Jenkins Pipeline. I tried many Groovy Script examples posted on SO and other forums but either the feature is blocked or I get method not found or whatever.
This seems to be the easiest
def DOCKER_FILES_DIR = './dockerfiles'
// ...
def dir = new File(DOCKER_FILES_DIR);
def dockerfiles = [];
dir.traverse(type: FILES, maxDepth: 0) {
dockerfiles.add(it)
}
But this resolves the relative path incorrectly, so I get this error:
java.io.FileNotFoundException: /./dockerfiles
I also tried to wrap it in dir
with:
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)
}
}
But got the same error:
java.io.FileNotFoundException: /./dockerfiles
This does not give an error, but only adds one file to the list:
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())
}
The contents of dockerfiles
is then missing all the files but the first one:
['py365']
Here is a minimal Pipeline to reproduce it in 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}"
}
}
And the output, showing that only bar1
is printed:
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
You can't really make use of the new File
and normal Groovy/Java ways to traverse file systems. The call is security checked by default (see JENKINS-38131) and won't even generally work because of how Jenkins Pipelines executes your pipeline code.
One way you could do this would be to use the findFiles
step from the Pipeline Utility Steps plugin. It returns a FileWrapper[]
which can be inspected/used for other purposes.
node {
// ... check out code, whatever
final foundFiles = findFiles(glob: 'dockerfiles/**/*')
// do things with FileWrapper[]
}
Another option is to shell out and capture the standard out:
node {
// ... check out code, whatever
final foundFiles = sh(script: 'ls -1 dockerfiles', returnStdout: true).split()
// Do stuff with filenames
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With