Cómo elegir dinámicamente una twig de git para usar en la compilation de Jenkins

Intento crear una nueva configuration de proyecto para el server de compilation Jenkins. Para simplificar lo que estoy tratando de hacer, usaré solo dos componentes para describir el problema.

Componente A

  • El cambio en este componente desencadena la construcción de este proyecto en el server de CI.
  • El server de CI tiene una twig configurada estáticamente para monitorear cambios y compilation. P.ej. dominar o desarrollar una sucursal.
  • Este componente contiene un file de configuration con la versión requerida de ComponentB de la que depende.

Componente B

  • Los cambios en este componente no desencadenan la compilation de este proyecto en el server de CI (habrá otro proyecto para cubrir el desarrollo de ComponentB).
  • Las versiones individuales del componente están labeldas
  • ComponentA ha requerido la versión de ComponentB en su file de configuration
  • El server de CI no sabe qué bifurcación (label) pagará hasta que el file de configuration de ComponentA se analice de alguna manera.

¿Cuál es la forma correcta de lograr esto en Jenkins? Estaba tratando de descubrir cómo agregar este comportamiento dynamic de analizar el file de configuration y hacer que Git Plugin revise la twig en function de la versión esperada de ComponentB, pero hasta ahora no tengo ni idea.

En el siguiente paso, es posible que desee tener comodines (como 5.3. *) En el file de configuration, así que tendré que search la label más nueva de ComponentB que coincida con el comodín.

EDITAR

Ahora veo que simplifiqué demasiado mi problema y debido a la simplificación, la principal limitación ya no está presente.

La principal limitación es que los componentes A y B deben buildse juntos. No es posible comstackrlos por separado, ya que forman un ejecutable / biblioteca y el script de compilation necesita files fuente de ambos componentes.

Si pregunta por qué una configuration tan extraña, demos a los componentes A y B alguna descripción:

  • ComponentA: código específico de la plataforma nativa
  • ComponentB: código independiente de la plataforma nativa

Puede haber muchos Componente As – uno para cada plataforma, pero solo el Componente B. La combinación de A a B particular produce código fuente completo para una sola plataforma, pero no todas las plataforms pueden actualizarse a la última versión de B, por lo que necesita tener control sobre qué versión de B debería usarse para build.

Una opción para lograr lo que desea es usar la siguiente configuration:

Crea dos trabajos de Jenkins:

  • "Componente A" (automáticamente activado en cambios de SCM)
  • "Componente B" (activado "manualmente")

Paso 1

Defina el parámetro de compilation de branch para "Componente B":

enter image description here

Utilice este parámetro como el especificador de sucursal "Git Plugin":

enter image description here

Ahora debería poder activar manualmente la creación del "Componente B", especificando un parámetro de bifurcación (label) adecuado para ello, por ejemplo, tags/5.3.0 .

Paso 2

Agregue un nuevo paso de compilation "Ejecutar Shell" a su compilation "Componente A", que extraerá la versión "Componente B" del file de configuration en el área de trabajo y preparará el file b.properties con los parameters de compilation "Componente B".

enter image description here

Instale un complemento Jenkins Trigger parametrizado y agregue un nuevo paso de compilation "Disparar / invocar construcciones en otros proyectos" al trabajo "Componente A":

enter image description here

Usando su file b.properties como fuente de parameters de compilation.

Ahora, cada vez que se reconstruye el "Componente A", se activará una nueva compilation del "Componente B", con la twig / label de destino como parámetro de compilation.

Agregar soporte comodín

Si desea admitir versiones de comodines, puede usar el git ls-remote para search la última label, así:

 #B=$(obtain B version from the config file in a usual way) LATEST=$(\ git ls-remote --tags YOUR_REPOSITORY_URL "$B"\ |cut -d / -f3|sort -r --version-sort|head -1\ ) cat <<EOF > b.properties branch=tags/$LATEST EOF 

Esto mostrará una list de todas las tags, que coincidan con el patrón de versión "B", en el repository "Componente B" remoto, y saveá el último número de versión en la variable LATEST RECIENTE.

Agregue esto a su paso "Ejecutar Shell" del trabajo "Componente A", y debería ser capaz de manejar patrones de numbers de versión como: 5.3.*

El problema es que el script de shell se ejecutará como el usuario de demonio de Jenkins, por lo que debe tener las cnetworkingenciales adecuadas configuradas, para acceder al repository de Git remoto (por ejemplo, a través de ssh pubkey).

Alternativamente, es posible que desee examinar el complemento de enlace de cnetworkingenciales , para reutilizar las cnetworkingenciales de Git almacenadas en Jenkins.

Usando la tubería de estilo Jenkins 2.0

También puede resolver la tarea en cuestión utilizando un Pipeline Jenkins 2.0-style, que le permitirá consultar el código de los componentes A y B, en un único espacio de trabajo, y luego aplicarles algún paso de compilation común.

Tu canalización podría verse más o less así:

 node { //Settings def cnetworkingentialsId = '8fd28e34-b04e-4bc5-874a-87f4c0e05a03' def repositoryA = 'ssh://git@stash.com/projects/a.git' def repositoryB = 'ssh://git@stash.com/projects/b.git' stage('Checkout component A') { git cnetworkingentialsId: cnetworkingentialsId , url: repositoryA , branch : "master" } stage("Resolve and checkout component B") { def deps = readProperties file: 'meta.properties' echo "Resolved B version = ${deps['b']}" dir("module/b") { //Clone/Fetch Component B checkout scm:[ $class: 'GitSCM', userRemoteConfigs: [[url: repositoryB, cnetworkingentialsId: cnetworkingentialsId]], branches: [[name: 'refs/tags/*']] ], changelog: false, poll: false //Checkout the tag, matching deps['b'] pattern sshagent([cnetworkingentialsId]) { sh "git checkout \$(git tag -l \"${deps['b']}\" |sort -r --version-sort|head -1)" } } } stage("Build A+B") { //Apply a common build step } } 

Aquí usamos el command "readProperties", que es parte del complemento de Pipeline Utility Steps para extraer el patrón de versión "Component B" de meta.properties . También hay commands readYaml, readJSON disponibles.

A continuación, buscamos / clonamos el "Componente B", con el changelog: false, poll: false indicadores changelog: false, poll: false , para evitar que se registre para la encuesta SCM, en la carpeta "module / b" del espacio de trabajo actual.

A continuación, invoque un command de shell para seleccionar la label, en function del patrón de versión que hemos obtenido anteriormente, y cárguelo (los comodines de estilo 5.3. * También deberían funcionar).

La invocación sh , está envuelta en el sshagent , para que reutilice las cnetworkingenciales apropiadas de la tienda de cnetworkingenciales de Jenkins.

Usar el Plugin de enlace de cnetworkingenciales funcionó muy bien para mí (también mencionado por @zeppelin)

Pasos:

En la sección de cnetworkingenciales globales :

  1. Add Cnetworkingentials del tipo: "Nombre de usuario con contraseña" . Este debe ser el nombre de usuario y la contraseña para el server Git del repository del componente B utilizando el protocolo HTTPS (la opción SSH no es buena para este propósito)

enter image description here

En su configuration de trabajo de Jenkins:

  1. Coloque el componente A en la Gestión de código fuente regular bajo la sección Git todos los campos requeridos ( Repositorios , Sucursales , etc.).
    • Será más claro y más limpio colocar el repository en un subdirectory: en Comportamientos Adicionales, select Check out to a sub-directory y escriba: component_a
  2. Asegúrese también de verificar en Build Triggers the Build when a change is pushed to GitHub
  3. En la sección Entorno de construcción, marque la casilla Use secret text(s) or file(s)

    • poner en Variable algún nombre: MY_CRED
    • en Cnetworkingentials elija las cnetworkingenciales específicas que creó en el paso 1.

    enter image description here

  4. Ahora, usando MY_CRED en el código de shell Execute , tendrá acceso al repository del componente B:

     DIR="component_b" if [ "$(ls -A $DIR/.git)" ]; then cd $DIR git fetch else git clone https://$MY_CRED@github.com/proj/component_b.git $DIR cd $DIR fi git show 

    enter image description here

    • Nota : NO verá el usuario y la contraseña en los loggings, por lo que debería ser seguro. Verás: git clone 'https://****@github.com/proj/component_b.git' component_b
  5. Haga todos los análisis de configuration del componente A para get la label deseada: TAG=$(cat ./component_a/config.cfg | grep ... | sed ...)

  6. Verifique la label deseada: cd component_b; git checkout -f $TAG cd component_b; git checkout -f $TAG
    • Nota: la label -f force.
  7. Ahora ejecuta el código y testing como desees …

1 – ¿Sería una posible solución agregar el proyecto B como un sub repository del proyecto A ?

2- (si realmente se debe include el código fuente completo para B): ¿ B_builds comstackciones de B a algún repository de B_builds , y agregar este repository como un sub-repo de A sería una posible solución?


Justificación: una forma de hacer que la dependencia entre A y B más explícita es representarla dentro de las dependencies del repository.

Esto requeriría agregar un paso adicional al administrar el proyecto A :

 update `B` sub repo in `A` project, and push this to `A` 

cada vez que produces una nueva versión para B

Sin embargo, usted tendría una visión clara, desde A , sobre cuándo se integraron las versiones de B (por ejemplo: "solo usamos B 2.0.1 comenzando desde A 4.3.2 "), y presionar hacia A activaría su flujo habitual de Jenkins .