Je ne peux pas créer une simple liste de noms de fichiers dans un répertoire donné dans un pipeline Jenkins scripté. J'ai essayé de nombreux exemples de scripts Groovy publiés sur SO et d'autres forums, mais soit la fonctionnalité est bloquée, soit la méthode est introuvable ou autre).
Cela semble être le plus simple
def DOCKER_FILES_DIR = './dockerfiles'
// ...
def dir = new File(DOCKER_FILES_DIR);
def dockerfiles = [];
dir.traverse(type: FILES, maxDepth: 0) {
dockerfiles.add(it)
}
Mais cela résout le chemin relatif de manière incorrecte, donc j'obtiens cette erreur:
Java.io.FileNotFoundException: /./dockerfiles
J'ai également essayé de l'envelopper dans dir
avec:
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)
}
}
Mais j'ai la même erreur:
Java.io.FileNotFoundException: /./dockerfiles
Cela ne donne pas d'erreur, mais n'ajoute qu'un fichier à la liste:
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())
}
Le contenu de dockerfiles
manque alors tous les fichiers sauf le premier:
['py365']
Voici un Pipeline minimal pour le reproduire dans 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}"
}
}
Et la sortie, montrant que seul bar1
est imprimé:
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
Vous ne pouvez pas vraiment utiliser le new File
et les méthodes Groovy/Java normales pour parcourir les systèmes de fichiers. La sécurité de l'appel est vérifiée par défaut (voir JENKINS-38131 ) et ne fonctionnera même pas en raison de la façon dont Jenkins Pipelines exécute votre code de pipeline.
Une façon de procéder serait d'utiliser l'étape findFiles
à partir des étapes de l'utilitaire de pipeline plugin . Il renvoie un FileWrapper[]
qui peut être inspecté/utilisé à d'autres fins.
node {
// ... check out code, whatever
final foundFiles = findFiles(glob: 'dockerfiles/**/*')
// do things with FileWrapper[]
}
Une autre option consiste à décortiquer et capturer la sortie standard:
node {
// ... check out code, whatever
final foundFiles = sh(script: 'ls -1 dockerfiles', returnStdout: true).split()
// Do stuff with filenames
}
Celui-ci fonctionne, mais c'est moche comme l'enfer:
#!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}"
}
}