tools template stages reuse library jenkins groovy shared-libraries jenkins-pipeline

template - Cargar Jenkins Pipeline Shared Library desde el mismo repositorio



jenkins pipeline tools (4)

TL; DR ¿Hay alguna forma de importar código en el Jenkinsfile desde el repositorio local (que no sea el paso de load )?

¿Por qué?

Experimenté que para las compilaciones complejas, el Jenkinsfile vuelve un poco voluminoso y no es muy Jenkinsfile de mantener.
Ahora que el trabajo de compilación es un código, sería maravilloso tener los mismos medios que para otro código. Es decir, me gustaría dividirlo en unidades más pequeñas (más mantenibles) y probarlas por unidad .

Lo que intenté

  • bibliotecas compartidas : permite dividir nuestra lógica Jenkins Pipeline en archivos más pequeños en un módulo separado e incluso una prueba de unidad.
    Sin embargo, deben estar en un repositorio diferente y (si no está en GitHub) deben configurarse en Jenkins.
  • Paso de load : permitir la carga de guiones geniales desde el repositorio.
    Sin embargo, los archivos deben ser secuencias de comandos y no clases "completas", lo que dificulta tener varios archivos o clases que dependan entre sí. Por ejemplo, la herencia es imposible.
    Además, estos archivos no se muestran cuando se hace una replay en un trabajo de Jenkins, lo que dificulta su desarrollo y depuración.

Mis preguntas

  • ¿Hay alguna forma (o solución alternativa) de crear una biblioteca compartida en el mismo repositorio que el Jenkinsfile e importar esta biblioteca al Jenkinsfile ?
  • ¿O hay alguna otra forma que no haya probado todavía?

Ejemplo de estructura de directorio

Similar a la estructura de directorios descrita para las bibliotecas compartidas, me gustaría tener lo siguiente en un solo repositorio .

(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


Puede echar un vistazo al complemento que escribí, que habilita el uso de subdirectorios de repositorio donde su canalización es como bibliotecas compartidas: https://github.com/karolgil/SharedLibrary

Después de construirlo e instalarlo, simplemente puede poner lo siguiente en su canalización:

@SharedLibrary(''dir/in/repo'') _

Para comenzar a usar dir/in/repo como biblioteca compartida para sus tuberías.



Solución:

library identifier: ''shared-library@version'', retriever: legacySCM(scm)

El enfoque que se toma actualmente en PR 37 no funcionará correctamente con los agentes de compilación, y de todos modos solo funcionará para los scripts usando el paso de la library , no la anotación de @Library .

Por cierto, los archivos cargados desde el paso de load aparecen en Replay . Pero es cierto que su script no puede referirse estáticamente a tipos definidos en tales archivos. En otras palabras, podría simular bibliotecas vars/*.groovy pero no src/**/*.groovy la misma limitación que la PR 37 actual.


Supongo que la forma correcta de hacerlo es implementar un SCMRetriever personalizado.

Sin embargo, puedes usar el siguiente hack:

Suponiendo que jenkins/vars/log.groovy en su repositorio local contiene:

def info(message) { echo "INFO: ${message}" }

Su Jenkinsfile puede cargar esa biblioteca compartida desde el directorio jenkins/ usando el paso de la library :

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 } }