2012-08-22 17 views
11

Vamos a usar Ivy con Ant, y haremos que Jenkins haga nuestras compilaciones. Originalmente pensé que hacer que Jenkins hiciera un <ivy:cleancache/> antes de ejecutar una compilación sería una buena idea. (Sería parte del objetivo "limpio" obligatorio).Ivy, Ant, Jenkins: ¿es una buena idea utilizar <ivy: cleancache> en las compilaciones de Jenkins?

Sin embargo, ahora veo que <ivy:cleancache> no solo limpia cosas desde <ivy:cachepath>, sino que realmente elimina todo el directorio $HOME/.ivy/cache.

Mi preocupación es que si Jenkins hace un <ivy:cleancache> en todas las compilaciones antes de que comiencen, interferirá con otras compilaciones que Jenkins podría estar ejecutando.

Está haciendo un <ivy:cleancache> una buena idea, especialmente si un solo usuario puede estar haciendo compilaciones múltiples al mismo tiempo?

De hecho, ¿qué ocurre cuando haces un <ivy:cachepath pathid="compile.path"/> en múltiples proyectos? ¿Esto también afecta algo como Jenkins? ¿Se confundirá Jenkins si varias compilaciones están compilando el compile.cachepath al mismo tiempo?

Respuesta

7

En mi opinión, ejecutar la tarea de limpieza de ivy con cada compilación es excesiva y elimina uno de los principales beneficios de usar ivy, la descarga inteligente de dependencias de terceros.

Dicho esto como se indica en la siguiente pregunta Maven relacionada, todos los caches pueden ensuciar y deben ser purgado periódicamente:

When is it safe to delete the local Maven repository?

par de recomendaciones:

uso dedicado trabajo de Jenkins (s) para purgar caché de hiedra

Mi primera recomendación es crear un trabajo periódico de Jenkins que invoque el siguiente objetivo limpio en su compilación:

<target name="clean-all" depends="clean"> 
    <ivy:cleancache/> 
</target> 

Esto asegura que Jenkins decide cuando la caché se purga y se puede programar que suceda fuera de los horarios normales de generación (por ejemplo 2am el primero de cada mes)

aislado de cada proyecto mediante el uso de múltiples cachés

Mi segunda recomendación aumenta el aislamiento entre las compilaciones de tus proyectos. Configure cada proyecto para que tenga su propia caché privada, utilizando la directiva caches. en tu archivo de configuración de hiedra.

+0

Gracias. Limpiar la caché solo agrega unos 90 segundos a la compilación (tenemos un repositorio Maven de la compañía local). No afecta el concepto _CI_, por lo que no le haría daño a Jenkins comenzar cada compilación con un caché limpio. Los desarrolladores pueden cerrar configurando ivy.cleancache en false. Irónicamente, la limpieza del caché irrita a los desarrolladores porque alarga la construcción, pero no los afecta. A Jenkins no le importa, pero si Jenkins está ejecutando múltiples trabajos, puede ser un problema. –

3

Aquí es lo que he decidido hacer:

He modificado mi archivo ivysettings.xml a tener la siguiente:

<ivysettings> 
    <properties environment="env." override="false"/> 
    <caches 
     defaultCacheDir="${ivy.default.ivy.user.dir}/cache-${env.EXECUTOR_NUMBER}" 
     resolutionCacheDir="${ivy.dir}/../target/ivy.cache"/> 
    <settings defaultResolver="default"/> 
    <include file="${ivy.dir}/ivysettings-public.xml"/> 
    <include url="${ivy.default.settings.dir}/ivysettings-shared.xml"/> 
    <include url="${ivy.default.settings.dir}/ivysettings-local.xml"/> 
    <include url="${ivy.default.settings.dir}/ivysettings-main-chain.xml"/> 
    <include url="${ivy.default.settings.dir}/ivysettings-default-chain.xml"/> 
</ivysettings> 

Esto hace dos cosas:

  • Se define el Ivy local cache como $HOME/.ivy/cache-$EXECUTOR_NUMBER donde $EXECUTOR_NUMBER es el ejecutor de Jenkins. Esto significa que cada ejecutor obtiene su propio caché Ivy. Por lo tanto, si Jenkins está ejecutando más de un trabajo a la vez, cada trabajo será recogido con un ejecutor diferente, por lo que tendrá su propio caché. Si un trabajo quiere limpiar el caché, puede seguir adelante.
  • He definido el caché de resolución en ${basedir}/target/ivy.cache. Esto le da a cada trabajo su propia caché de resolución que es bastante pequeña. Pero, de esta forma, la resolución de la hiedra no interfiere con otros trabajos si Jenkins está creando múltiples revisiones del mismo proyecto de Ivy.

El único inconveniente es que el directorio de caché predeterminado del usuario se llama $HOME/.ivy/cache-$env.EXECUTOR_NUMBER que no es un sitio bonito. Me encantaría que sea más razonable $HOME/.ivy/cache-0, pero no me he dado cuenta. Sin embargo, realmente no afecta nada en este punto.

Ahora, un desarrollador tiene un solo caché Ivy que contiene todos los frascos que ha descargado. De esta forma, los archivos jar se pueden compartir entre proyectos, lo que acelera las cosas para los desarrolladores.

Mientras tanto, Jenkins puede limpiar el caché Ivy con la frecuencia que está configurado. Esto podría hacerse para cada trabajo, o una vez por día o por mes. Sin embargo, dado que la caché se realiza por ejecutor, no tendré un problema con la limpieza de la caché, mientras que otra tarea (que se estaría ejecutando en otro ejecutor) dependerá de esa caché.

Esto debería resolver todos los problemas particulares. Lo único que me gustaría hacer es averiguar cómo establecer una variable predeterminada EJECUTOR_NUMBER si aún no se ha configurado. He intentado varias cosas como esta:

<ivysettings> 
    <property name="env.EXECUTOR_NUMBER" value="0" override="false"/> 
    <properties environment="env." override="false"/> 
    <caches 
     defaultCacheDir="${ivy.default.ivy.user.dir}/cache-${env.EXECUTOR_NUMBER}" 
     resolutionCacheDir="${ivy.dir}/../target/ivy.cache"/> 
    <settings defaultResolver="default"/> 
    <include file="${ivy.dir}/ivysettings-public.xml"/> 
    <include url="${ivy.default.settings.dir}/ivysettings-shared.xml"/> 
    <include url="${ivy.default.settings.dir}/ivysettings-local.xml"/> 
    <include url="${ivy.default.settings.dir}/ivysettings-main-chain.xml"/> 
    <include url="${ivy.default.settings.dir}/ivysettings-default-chain.xml"/> 
</ivysettings> 

Pero, en vano. He cumplido con cambiar los parámetros override tanto en el archivo <property> como en el archivo <properties> de diferentes formas, pero no hace exactamente lo que quiero.

2

Simplemente algo que he estado haciendo mucho para resolver el último problema que tienes.

puede agregar a este a las propiedades de la Jenkins Ant Build Pasos

another.less.obtrusive.name=${EXECUTOR_NUMBER} 

y añadir a ivysettings.xml.

Por lo que será "0" para todos, a excepción de Jenkins porque inyectará esta propiedad a ANT.

Algo sobre la pregunta principal: En Jenkins, siempre empiezo nuevo. Las construcciones de CI deben ser robustas, exhaustivas. Rápido es un subproducto bienvenido, pero no una motivación.

+1

Buena idea. Lo que hice fue configurarlo en mi 'ivy.tasks.xml', que todos deben importar de todos modos. Hago un ' luego de eso' 'property name =" env.EXECUTOR_NUMBER "value =" 0 "/>. Luego, hago mi tarea ''. Tenemos que importar el entorno de todos modos porque requiero que nuestros desarrolladores incorporen la información de compilación de Jenkins en frascos, guerras y oídos. –

+0

Me tomó más tiempo de lo que me gustaría admitir: el nombre de la variable 'EJECUTOR' enumerado en esta respuesta está mal escrito. Debe ser $ {EJECUTOR_NUMBER} –

Cuestiones relacionadas