nov.
2009
Déploiement d'artefacts dans un repository Maven depuis Ant/Ivy et Gradle
Tags : ant, archiva, artifactory, gradle, ivy, nexus
L'objectif de cet article de vous montrer comment déployer les artefacts produits par un projet dans un repository de type Maven2. Le repository contiendra les artefacts déployés et les méta données Maven générées. Cet article illustre le cas d'utilisation dont le projet est géré par le couple Ant/Ivy ou par Gradle.
Maven est un système de build complet gérant la construction de vos applications, la gestion des dépendances tierces dont votre application a besoin pour compiler, tester ou s'exécuter. Maven est également un outil de reporting capable de générer un ensemble de métriques sur le projet. Maven a des avantages et des inconvénients. Dans tous les cas, le choix de Maven pour builder vos applications dépend de votre contexte : type d'application à builder, existant, ouverture vers Internet, .... Mais au delà de l'outil, la force de Maven est de proposer des repositories de binaires comportant la quasi totalité des librairies open sources du marché. Chaque librairie, est couplée à un ensemble de méta données décrivant le projet de la librairie et ses dépendances. Avec ces méta données Maven, nous pouvons définir au sein de notre projet, une dépendance vers un projet et récupérer toutes les librairies nécessaires pour l'utilisation de ce projet.
Dans une infrastructure d'entreprise, vous installez des gestionnaires de repository comme Apache Archiva, Jfrog Artifactory ou Sonatype Nexus. Ces outils vous fournissent des services de proxy et vous permettre de disposer des repository permettant de contenir des librairies d'entreprises.
Quant à Ivy, il est un gestionnaire de dépendance à part entière capable capable de récupérer des librairies dans des repositories. Ivy est un outil flexible vous permettant de dialoguer avec des repository ayant une organisation et une localisation comme vous le voulez.
Mais comme expliqué précédemment, il est très pratique de récupérer nos dépendances depuis des repository Maven, et notamment depuis des gestionnaire de repository comme Nexus. Ivy adresse par défaut les deux mondes : récupérer des artefacts dans des repository Ivy avec des méta données Ivy et récupérer des artefacts dans des repositories Maven avec des meta-données Maven.
Mais nous voulons aussi que nos repositories Maven puissent contenir nos applications construites par Ivy. Pour construire nos applications, Ivy est couplé à un builder. Nous allons voir comment déployer des artefacts depuis Ivy couplé avec Ant ou couplé avec Gradle.
Ant/Ivy
Ant est le pionner des outils de build. Un script Ant définit une chaîne de build composée d'un ensemble de cibles (target) qui vont s'enchaîner. Chaque cible va constituer une étape de build, délegant le travail à un ensemble de tâches Ant. Nous couplons ensuite Ant au gestionnaire de dépendances Ivy pour gérer l'aspect téléchargement et déploiement.
Voici les éléments de configuration nécessaire:
Définition du repository Maven distant qui va contenir nos artefacts
Dans le fichier de configuration globale du projet Ivy (ivysettings.xml), nous déclarons un repository de type Maven2.
<ibiblio name="nexus" m2compatible="true" root="http://localhost:8081/nexus/content/repositories/thirdparty"/>
Définition des informations de sécurité
Les informations de sécurité sont définies au niveau de l''initialisation de Ivy dans le projet, après avoir chargé le fichier de configuration gloable
<target name="ivy-init"> <ivy:settings file="${ivy.settings.dir}/ivysettings.xml" refid="ivy.classpath"> <credentials host="localhost" realm="Sonatype Nexus Repository Manager" username="deploy_user" passwd="deploy_pwd"/> </ivy:settings> </target>
Génération de la méta donnée Maven
Les gestionnaires de repositories comme Archiva ou Nexus sont centriques Maven. Il est nécessaire de générer un descripteur Maven (pom.xml) pour notre projet Ant/Ivy. Cette génération est réalisée par la tâche ivy:makepom qui définie le mapping entre les configurations Ivy et les configurations Maven.
Par exemple:
<target name="makepom"> <ivy:makepom ivyfile="${ivy.file}" pomfile="dist/demo-core.pom"> <mapping conf="compile" scope="compile" /> <mapping conf="test" scope="test" /> </ivy:makepom>
Définition de notre cible de déploiement
<target name="deploy2Nexus" depends="jar, makepom, release-version"> <ivy:info file="${ivy.file}" property="info" /> <ivy:publish resolver="nexus" pubrevision="${info.revision}" overwrite="true" status="release" forcedeliver="false" artifactspattern="${dist.dir}/[artifact].[ext]" /> </target>
L’invocation de la cible deploy2Nexus va nous deployer les artefacts suivants
- l’artefact binaire demo-core-2.1.jar
- la méta donnée Maven demo-core-2.1.pom
- la méta donnée Ivy: ivy-2.1.xml
- un fichier sha1 et md5 pour chaque fichier précédent, afin de vérifier ultérieurement l’intégrité du téléchargement
Note: Il faut rajouter l'attribut 'publishivy' avec la valeur 'false' à la tâche 'ivy:publish' si nous voulons que le fichier 'ivy.xml' ne soit pas déployé.
Gradle
Gradle est un système de build complet offrant les conventions de Maven et la flexibilité de Ivy. Voici les éléments de configuration nécessaires:
Définition du repository Maven distant qui va contenir nos artefacts avec les informations de sécurités
uploadArchives{ repositories.mavenDeployer{ repository(url:"http://localhost:8081/nexus/content/repositories/thirdparty/"){ authentication(userName:'deploy1', password:'deploy1') } } }
Avec les informations Maven suivantes:
usePlugin 'maven' group='boissinot.net' version='2.1'
Déploiement
Invoquer la phase uploadArchives du cycle de vie du plugin _java_
$ gradle clean uploadArchives
L’invocation de la tache uploadArchives va nous déployer les artefacts suivants:
- l'artefact binaire demo-core-2.1.jar
- la méta donnée Maven demo-core-2.1.pom
- un fichier maven-metada.xml (au niveau du répertoire version) contenant les informations de versions déployées et la date du dernier déploiement d’une version
- un fichier sha1 et md5 pour chaque fichier précédent
Note 1: La méta donnée Ivy n’est pas déployée par défaut et un descripteur Maven est généré automatiquement.
Note 2: Pour déployer dans un repository Maven, Gradle utilise la technologie Maven par l’intermédiaire des Maven Ant Tasks qu’il incorpore. Ainsi, les méta données Maven générées sont 100% Maven compatible.
Cas d'une SNAPSHOT Maven
Au sein du système de build Maven, le mot clé SNASPHOT signifie version en cours de développement.
Avec Ant/Ivy
L’invocation de la cible deploy2Nexus va nous deployer les artefacts suivants
- l’artefact binaire demo-core-2.1-SNAPSHOT.jar
- la méta donnée Maven demo-core-2.1-SNAPSHOT.pom
- l’artefact Ivy : ivy-2.1-SNAPSHOT.xml
- un fichier sha1 et md5 pour chaque fichier précédent, afin de vérifier ultérieurement l’intégrité du téléchargement
Notons que l 'artefact SNAPSHOT déployé par le couple Ant/Ivy dans Nexus est unique: si nous essayons de redéployer de nouveau, l’artefact précédent est écrasé. Ivy n’a pas la possibilité de modifier le paramètre uniqueVersion au niveau de la définition du repository comme c’est le cas avec le plugin maven-deploy-plugin http://maven.apache.org/plugins/maven-deploy-plugin/examples/disabling-timestamps-suffix.html Ainsi, on garde uniquement la dernière version de l’artefact SNAPSHOT. Nous tombons ici dans les limitations de l'outil Ivy dans le cadre d'un déploiement dans une infrastructure Maven.
Avec Gradle
Essayons le déploiement d'un artefact SNAPSHOT avec Gradle:
usePlugin 'maven' group='boissinot.net' version='2.1-SNAPSHOT' uploadArchives{ repositories.mavenDeployer{ snapshotRepository(url:"http://localhost:8081/nexus/content/repositories/thirdpartySnap/"){ authentication(userName:'deploy_user', password:'deploy_pwd') } } }
L’invocation de la tache uploadArchives va nous déployer les artefacts suivants
- l’artefact binaire demo-core-2.1-20091115.155011-1.jar
- la méta donnée Maven demo-core-2.1-20091115.155011-1.pom
- le fichier maven-metadata.xml dans le dossier parent contenant les informations de versions déployées et la date du dernier déploiement d’une version
- un fichier maven-metatdata.xml dans le dossier d’artefact
Remarque: Gradle s’insère parfaitement dans une infrastructure Maven existante y compris avec des artefacts SNAPSHOT.
Note: Comme dans le cas précédent, il utilise les Maven Ant Tasks. Le clef SNAPSHOT est remplacé par le timestamp de la date de déploiement comme dans le cas d'un deployer avec Maven.
Limitation: Mais dans certaines situations, nous voulons au contraire une unique version SNAPSHOT. Malheureusement, Gradle ne le gère actuellement pas.
Variantes avec les autres gestionnaires de repositories
Archiva
Le protocole de déploiement dans Archiva est webdav. Le déploiement depuis Ant/Ivy ou Gradle dans un Archiva non sécurisé s'efectue sans problèmes. Néanmoins, dans un contexte sécurisé, uniquement l'outil Gradle semble fonctionner.
Artifactory
Variantes de sécurité pour Ant/Ivy
Fichier settings.xml
<ibiblio name="artifactory-snap" m2compatible="true" root="http://localhost:8081/artifactory/libs-snapshots-local"/>
Fichier build.xml
<credentials host="localhost" realm="Artifactory Realm" username="deploy_user" passwd="deploy_pwd" />
Modification des versions uniques dans le cas de SNAPSHOT
Avec Artifactory, vous avez la possibilité de configurer au niveau de votre repository SNAPSHOT d'entreprise (géré par Artifactory), la propriété 'Snapshot Version Behavior' qui peut prendre trois valeurs:
- Unique: une Snapshot pour chaque déploiement, c'est a dire que le mot clef SNAPSHOT sera remplacé par le timestamp de la date du déploiement
- Non-unique: un et un seul artefact. L'artefact deployé gardera le nom SNAPSHOT.
- Deployer: en fonction du client de déploiement.
A noter: Artifactory offfre également la possibilité de limiter le nombre de SNAPSHOT unique.
Finalisation de la solution
Dans le cadre de Gradle, il est souhaitable d’extraire les informations de sécurité du script de build. Pour cela, le plus simple est de créer un fichier gradle.properties dans l'espace du compte utilisateur exécutant Gradle (~/.gradle).
archivaUser=deploy_user archivaPassword=deploy_pwd
Il vous suffit ensuite de mettre à jour le fichier build.gradle avec les propriétés crées précédemment
uploadArchives{ repositories.mavenDeployer{ repository(url:"http://localhost:8080/archiva/repository/snapshots/"){ authentication(userName: archivaUser, password: archivaPassword) } } }
Conclusion
Gradle s'insère parfaitement dans une infrastructure Maven existante, capable de déployer des artefacts et méta données Maven, y compris des méta données SNAPSHOT. La fonctionnalité 'Snapshot Version Behavior' de Artifactory fait de ce gestionnaire de repository un candidat très intéressant.
A noter: La dernière version de Artifactory permet de gérer directement des méta données Ivy.


Commentaires
En plus, un exemple ici pour déployer des artefacts avec leurs descripteurs dans un repository Maven.