TL; DR Existe-t-il un moyen d'importer du code dans le Jenkinsfile
à partir du référentiel local (autre que le load
étape)?
J'ai expérimenté que pour les builds complexes, le Jenkinsfile
devient assez volumineux et peu maintenable.
Maintenant que le travail de construction est du code, ce serait merveilleux d'avoir les mêmes moyens que pour les autres codes. C'est-à-dire que je voudrais le diviser en unités plus petites (plus faciles à maintenir) et tester les unités .
load
Step : permet de charger des scripts groovy à partir du référentiel.Jenkinsfile
et d'importer cette bibliothèque dans le Jenkinsfile
?Similaire à la structure de répertoires décrite pour bibliothèques partagées J'aimerais avoir les éléments suivants dans un seul référentiel .
(root)
+- someModule
| +- ...
+- jenkins # Classes/Scripts used by Jenkins in a separate module
| +- src # Groovy source files
| +- org
| +- foo
| +- Bar.groovy # for org.foo.Bar class
| +- test # Groovy test files
| +- org
| +- foo
| +- BarTest.groovy # Test for org.foo.Bar class
| +- pom.xml or build.groovy # Build for local library
+- Jenkinsfile # Build "someModule", uses classes from "jenkins" module
Solution de contournement:
library identifier: 'shared-library@version', retriever: legacySCM(scm)
L'approche actuellement adoptée dans PR 37 ne fonctionnera pas correctement avec les agents de build et ne fonctionnera de toute façon que pour les scripts utilisant l'étape library
, pas la @Library
annotation.
Au fait, les fichiers chargés à partir de l'étape load
do apparaissent dans Replay . Mais il est vrai que votre script ne peut pas faire référence statiquement à des types définis dans de tels fichiers. En d'autres termes, vous pouvez simuler la bibliothèque vars/*.groovy
mais non src/**/*.groovy
— la même limitation que le PR 37 actuel.
Je suppose que la bonne façon de le faire est d'implémenter un SCMRetriever
personnalisé.
Cependant, vous pouvez utiliser le hack suivant:
En supposant jenkins/vars/log.groovy
dans votre référentiel local contient:
def info(message) {
echo "INFO: ${message}"
}
Votre Jenkinsfile
peut charger cette bibliothèque partagée à partir du jenkins/
répertoire utilisant library
étape:
node('node1') { // load library
checkout scm
// create new git repo inside jenkins subdirectory
sh('cd jenkins && git init && git add --all . && git commit -m init &> /dev/null')
def repoPath = sh(returnStdout: true, script: 'pwd').trim() + "/jenkins"
library identifier: 'local-lib@master', retriever: modernSCM([$class: 'GitSCMSource', remote: repoPath])
}
node('node2') {
stage('Build') {
log.info("called shared lib") // use the loaded library
}
}
Vous pouvez jeter un oeil au plugin que j'ai écrit, qui permet d'utiliser des sous-répertoires de dépôt où votre pipeline est en tant que bibliothèques partagées: https://github.com/karolgil/SharedLibrary
Après l'avoir construit et installé, vous pouvez simplement mettre ce qui suit dans votre pipeline:
@SharedLibrary('dir/in/repo') _
Pour commencer à utiliser dir/in/repo
comme bibliothèque partagée pour vos pipelines.
Je voulais faire la même chose et j'ai fini par créer ceci:
https://github.com/jenkinsci/workflow-cps-global-lib-plugin/pull/37
et voici comment je l'utilise:
https://github.com/syndesisio/syndesis-pipeline-library/blob/master/Jenkinsfile#L
Dans mon cas, je voulais créer un fichier Jenkins qui en fait tests
la bibliothèque de pipelines que contient le référentiel.
Faites-moi savoir ce que vous pensez et n'hésitez pas à ajouter vos commentaires sur le RP.
J'ai trouvé que la version de Pawel avait des problèmes si vous extrayez le pipeline de SCM (non intégré dans la configuration de l'interface utilisateur du travail Jenkins). Ceci est ma version pour ces cas:
node {
def jenkinsDir = sh(returnStdout: true, script: 'pwd').trim().replaceAll('(.*)(@[0-9]*$)', '$1') + "@script/jenkins"
ssh("cd ${jenkinsDir} && ls -l vars/ && if [ -d .git ]; then rm -rf .git; fi; git init && git add --all . && git commit -m init &> /dev/null")
library identifier: 'local-lib@master', retriever: modernSCM([$class: 'GitSCMSource', remote: jenkinsDir])
stage('Build') {
log.info("called shared lib") // use the loaded library
}
}
Dans ces cas, le pipeline lui-même est extrait dans un autre espace de travail (même nom de répertoire mais avec @script
dans le nom) que l'endroit où le pipeline lui-même sera exécuté (et où votre code sera également extrait).
Le répertoire "jenkins" est uniquement disponible (au moins avec la dernière version avec le dossier "vars") dans l'espace de travail où le pipeline est extrait, car l'autre n'est pas encore extrait et à jour (peut-être même dans un branche différente).