déc 15

Depuis le 2 novembre, la version 1.1 du framework Play! est disponible.
Je ne vous ferai pas une présentation de ce framework, il en existe plusieurs dont celle du Touilleur Express (Play! Framework).

Je vais plutôt vous faire un retour d’expérience de la mise en place des outils nécessaires pour intégrer des applications Play! à notre usine d’Intégration Continue.

Commençons par la description de notre environnement, très classique :

  • tous les projets Java sont mavenisés (Maven 2).
  • tous les projets définissent des tests unitaires (JUnit).
  • certains projets ont des tests Selenium.
  • tous les projets ont des builds lancés automatiquement par Bamboo.
  • tous les projets sont analysés par Sonar chaque nuit

La tâche est de faire rentrer les futures applications écrites avec Play! dans cette chaîne d’Intégration Continue.

Mavenisation d’une application Play!

Il s’agit de l’étape qui fut la plus compliquée et surtout la plus longue. Le cahier des charges est le suivant :

  • Gestion des dépendances applicatives (ie: remplir le répertoire /lib avec les dependencies Maven du projet).
  • Gestion des librairies inclues dans le framework Play! (afin que la phase compile se passe correctement).
  • Maven doit pouvoir faire exécuter les tests unitaires et en récupérer un rapport Surefire.
  • Maven doit pouvoir exécuter Cobertura sur l’application et en extraire un rapport (à destination de Sonar).
  • Une analyse Sonar doit être effectuée sur l’application.

Gestion des dépendances applicatives

Avec un peu de configuration Maven, (plugin dependency), il est assez facile de faire exporter les librairies applicatives dans le répertoires lib de l’application, ainsi que de les supprimer lors d’un mvn clean.

  <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-dependency-plugin</artifactId>
        <version>2.1</version>
        <executions>
          <execution>
            <id>default-cli</id>
            <configuration>
              <includeClassifiers>,sources</includeClassifiers>
              <outputDirectory>lib/</outputDirectory>
              <excludeScope>provided</excludeScope>
              <!-- To download sources jars without failing -->
              <failOnMissingClassifierArtifact>false</failOnMissingClassifierArtifact>
              <excludeArtifactIds>play-runtime,play</excludeArtifactIds>
            </configuration>
         ...

Gestion des dépendances du framework Play!

Là, le boulot est un peu plus long car j’ai dû référencer toutes les librairies du framework. Cependant les versions sont très standard (mis à part un patch sur Hibernate), donc le boulot se fait bien.
Petit écueil : certaines librairies n’existent pas dans les repository standards. Il y en a donc certaines qui doivent être uploadées dans votre Nexus d’entreprise.

Ces 2 étapes doivent vous permettre de compiler un projet Play! sous Maven sans encombre.

Maintenant que la compilation fonctionne, préparons l’exécution des tests unitaires via le runtime de Play!

Le Runtime de Play! pour les Tests unitaires

Je sais que la pratique suivante fera bondir certains, mais le runtime de Play! est tout simplement beaucoup trop puissant pour que l’on puisse s’en passer !
Nous ne voulions pas devoir gérer l’installation du runtime sur les différents environnements où les agents Bamboo sont déployés. Il faut donc le packager sous forme de ressources avec ses modules intégrés dans le repository Maven. Une tâche Ant se chargera de le dézipper afin que la commande play soit accessible.

  <dependency>
    <groupId>org.play</groupId>
    <artifactId>play-runtime</artifactId>
    <version>1.1</version>
    <type>zip</type>
  </dependency>

Les tests unitaires

Les tests unitaires de Play! framework sont des tests JUnit mais lancés par le runtime Play!.

La commande auto-test permet de lancer les tests unitaires et les tests Selenium automatiquement. Un reporting sous forme de fichier html est généré. J’ai donc dû enrichir le framework pour générer un rapport au format Surefire. Ce rapport contient le nombre de tests unitaires joués, le nombre d’erreurs, d’echecs, le temps passé ainsi qu’un détail des erreurs.
Un script ant permet de faire lancer par Maven le framework Play! en mode auto-test.

Voici une exécution Maven du plugin mavent-antrun-plugin :

<execution>
  <id>UnitTests</id>
  <phase>test</phase>
  <configuration>
    <target>
      <property name="maven.project.artifactId" value="${project.artifactId}" />
      <property name="maven.project.version" value="${project.version}" />
      <property name="maven.project.play-runtime" value="play-runtime-${play.version}" />

      <property name="play.runtime.path" value="${basedir}/target/dependency/${maven.project.play-runtime}" />
      <property name="play.runtime.file" value="${basedir}/target/dependency/${maven.project.play-runtime}.zip" />
      <property name="play.runtime.unzip.path" value="${basedir}/target/dependency" />

      <!-- Check zipped Play! runtime is present. Build fails if not present -->
      <available file="${play.runtime.file}" property="play.runtime.present" />
      <echo message="Is Play! runtime present : ${play.runtime.present}" />

      <fail message="Error : Play! runtime could not be found at : ${play.runtime.file}">
        <condition>
          <not>
            <isset property="play.runtime.present" />
          </not>
        </condition>
      </fail>

      <!-- Delete existing Play! runtime -->
      <echo message="Deleting any existing unzipped Play! runtime ..." />
      <delete dir="play.runtime.unzip.path" failonerror="false" verbose="true" />

      <!-- Unzip Play! runtime -->
      <echo message="Unzipping Play! runtime ..." />
      <unzip src="${play.runtime.file}" dest="${play.runtime.unzip.path}" />
      <echo message="Play! runtime unzipped successfully." />
      <chmod dir="${play.runtime.path}" perm="ugo+x" includes="play" />

      <!-- launch play mvn:up to retrieve libs in /lib folder -->
      <condition property="playExtension" value=".bat">
        <and>
          <os family="windows" />
        </and>
      </condition>
      <condition property="playExtension" value="">
        <and>
          <os family="unix" />
        </and>
      </condition>
      <exec executable="${play.runtime.unzip.path}/${maven.project.play-runtime}/play${playExtension}">
        <arg value="mvn:up" />
      </exec>

      <!-- Launch Play war command -->
      <condition property="playExtension" value=".bat">
        <and>
          <os family="windows" />
        </and>
      </condition>
      <condition property="playExtension" value="">
        <and>
          <os family="unix" />
        </and>
      </condition>
      <exec executable="${play.runtime.unzip.path}/${maven.project.play-runtime}/play${playExtension}">
        <arg value="auto-test" />
      </exec>
    </target>
  </configuration>
  <goals>
    <goal>run</goal>
  </goals>
</execution>

L’étape des Tests Unitaires est désormais ok !

L’analyse Cobertura

Que serait une analyse Sonar sans le plugin Cobertura !

Heureusement, il existe un module Cobertura pour la framework Play! Il est très bien intégré puisqu’il suffit de le configurer dans votre application.conf et il l’analyse Cobertura sera effectuée durant la phase des tests unitaires. Un rapport est généré. Le seul travail à faire est de référencer dans Sonar l’emplacement de ce rapport pour que ce dernier puisse l’exploiter.

Je vous conseille la documentation de ce très bon module Play! : Documentation module Cobertura.

Le packaging

Un gros morceau là aussi.

Le packaging d’une application Play! doit être fait sous forme de war pour pouvoir être uploadé dans un repository Maven.
L’idée retenue est que l’on va laisser Maven exécuter sa phase package qui buildera un war non fonctionnel, puis une tâche Ant branchée sur cette même phase va générer grâce à la commande play war un fichier war Play! fonctionnel. Le principal soucis rencontré fût l’exclusion du répertoire target du packaging fait par Play! (notre target contient notamment le runtime Play!). Un développement soumis sur Github nous a permis de rajouter un paramètre –exclude à la ligne de commande play war et d’exclure les répertoires que nous ne voulions pas builder.

Voici l’exécution Maven du plugin Antrun :

<execution>
  <id>Packaging</id>
  <phase>package</phase>
  <configuration>
    <target>
      <property name="maven.project.artifactId" value="${project.artifactId}" />
      <property name="maven.project.version" value="${project.version}" />
      <property name="maven.project.play-runtime" value="play-runtime-${play.version}" />

      <property name="play.runtime.path" value="${basedir}/target/dependency/${maven.project.play-runtime}" />
      <property name="play.runtime.file" value="${basedir}/target/dependency/${maven.project.play-runtime}.zip" />
      <property name="play.runtime.unzip.path" value="${basedir}/target/dependency" />

      <!-- Check zipped Play! runtime is present. Build fails if not present -->
      <available file="${play.runtime.file}" property="play.runtime.present" />
      <echo message="Is Play! runtime present : ${play.runtime.present}" />

      <fail message="Error : Play! runtime could not be found at : ${play.runtime.file}">
        <condition>
          <not>
            <isset property="play.runtime.present" />
          </not>
        </condition>
      </fail>

      <!-- Delete existing Play! runtime -->
      <echo message="Deleting any existing unzipped Play! runtime ..." />
      <delete dir="play.runtime.unzip.path" failonerror="false" verbose="true" />

      <!-- Unzip Play! runtime -->
      <echo message="Unzipping Play! runtime ..." />
      <unzip src="${play.runtime.file}" dest="${play.runtime.unzip.path}" />
      <echo message="Play! runtime unzipped successfully." />
      <chmod dir="${play.runtime.path}" perm="ugo+x" includes="play" />

      <!-- launch play mvn:up to retrieve libs in /lib folder -->
      <condition property="playExtension" value=".bat">
        <and>
          <os family="windows" />
        </and>
      </condition>
      <condition property="playExtension" value="">
        <and>
          <os family="unix" />
        </and>
      </condition>
      <exec executable="${play.runtime.unzip.path}/${maven.project.play-runtime}/play${playExtension}">
        <arg value="mvn:up" />
      </exec>

      <!-- Launch Play war command -->
      <condition property="playExtension" value=".bat">
        <and>
          <os family="windows" />
        </and>
      </condition>
      <condition property="playExtension" value="">
        <and>
          <os family="unix" />
        </and>
      </condition>
      <exec executable="${play.runtime.unzip.path}/${maven.project.play-runtime}/play${playExtension}">
        <arg value="war" />
        <arg value="${basedir}" />
        <arg value="-o" />
        <arg value="${basedir}/target/${maven.project.artifactId}-${maven.project.version}" />
        <arg value="--zip" />
        <arg value="--exclude" />
        <arg value="target" />
      </exec>
    </target>
  </configuration>
  <goals>
    <goal>run</goal>
  </goals>
</execution>

Nous avons donc les tests unitaires, l’analyse Cobertura, le packaging en War et le déploiement dans un repo Maven qui fonctionnent. Il ne nous reste plus qu’à attaquer l’analyse Sonar.

L’analyse Sonar

Avec un peu de configuration (emplacement des sources, des fichiers Surefire, Cobertura, etc…), la configuration du plugin Sonar s’est passée sans encombres.

Nous avons donc réussi à intégrer les applications Play! à notre usine d’Intégration Continue.
Les projets ont donc uniquement besoin d’un pom avec les bonnes dépendances pour pouvoir commencer leurs développements et qu’ils soient compatibles Usine de Développement.

Conclusion : malgré quelques difficultés, l’intégration du framework Play! s’est faite sans gros soucis. Nous avons ainsi pu rentrer dans le code du framework, autant du côté Python que du côté Java. Quelques Pull Request chez Github et nous sommes pleinement fonctionnels !

Merci à Play! framework et à toute son équipe !

Update 16/12/2010 :
Suite aux commentaires, voici le contenu du pom parent pour la version 1.1 de Play! :

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>org.play</groupId>
  <artifactId>play-parent</artifactId>
  <version>1.1</version>
  <packaging>pom</packaging>
  <name>Play's parent POM</name>
  
  <repositories>
    <!-- Repository containing Play! jars. If you have your own repo (ex: Nexus), upload missing libs in third-parties -->
    <repository>
      <id>infin-it</id>
      <url>http://nexus.infin-it.fr/content/groups/public</url>
      <releases>
        <enabled>true</enabled>
      </releases>
      <snapshots>
        <enabled>false</enabled>
      </snapshots>
    </repository>
  </repositories>  
    
  <properties>
    <play.version>1.1</play.version>
  </properties>

  <dependencies>
    <dependency>
      <groupId>javax.activation</groupId>
      <artifactId>activation</artifactId>
      <version>1.1.1</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>antlr</groupId>
      <artifactId>antlr</artifactId>
      <version>2.7.6</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>com.ning</groupId>
      <artifactId>async-http-client</artifactId>
      <version>1.2.0</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>org.bouncycastle</groupId>
      <artifactId>bcprov-jdk15</artifactId>
      <version>1.45</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>c3p0</groupId>
      <artifactId>c3p0</artifactId>
      <version>0.9.1.2</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>cglib</groupId>
      <artifactId>cglib-nodep</artifactId>
      <version>2.2</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>commons-beanutils</groupId>
      <artifactId>commons-beanutils</artifactId>
      <version>1.8.3</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>commons-codec</groupId>
      <artifactId>commons-codec</artifactId>
      <version>1.4</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>commons-collections</groupId>
      <artifactId>commons-collections</artifactId>
      <version>3.1</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>org.apache.commons</groupId>
      <artifactId>commons-email</artifactId>
      <version>1.2</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>commons-fileupload</groupId>
      <artifactId>commons-fileupload</artifactId>
      <version>1.2</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>commons-io</groupId>
      <artifactId>commons-io</artifactId>
      <version>1.4</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>commons-lang</groupId>
      <artifactId>commons-lang</artifactId>
      <version>2.5</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>commons-logging</groupId>
      <artifactId>commons-logging</artifactId>
      <version>1.1.1</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>dom4j</groupId>
      <artifactId>dom4j</artifactId>
      <version>1.6.1</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>net.sf.ehcache</groupId>
      <artifactId>ehcache-core</artifactId>
      <version>2.0.0</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>net.sf.ezmorph</groupId>
      <artifactId>ezmorph</artifactId>
      <version>1.0.3</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>org.codehaus.groovy</groupId>
      <artifactId>groovy-all</artifactId>
      <version>1.7.1</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>com.google.code.gson</groupId>
      <artifactId>gson</artifactId>
      <version>1.4</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>org.hibernate</groupId>
      <artifactId>hibernate-core</artifactId>
      <version>3.5.6-Final</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>org.hibernate</groupId>
      <artifactId>hibernate-annotations</artifactId>
      <version>3.5.6-Final</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>org.hibernate</groupId>
      <artifactId>hibernate-commons-annotations</artifactId>
      <version>3.2.0.Final</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>org.hibernate</groupId>
      <artifactId>hibernate-entitymanager</artifactId>
      <version>3.5.6-Final</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>org.hibernate.javax.persistence</groupId>
      <artifactId>hibernate-jpa-2.0-api</artifactId>
      <version>1.0.0.Final</version>
      <scope>provided</scope>
    </dependency>
    <!-- This lib must be added to your repository (comes from Sourceforge)-->
    <dependency>
      <groupId>hsqldb</groupId>
      <artifactId>hsqldb</artifactId>
      <version>1.8.1.2</version>
      <scope>provided</scope>
    </dependency>
    <!-- This lib must be added to your repository (comes from Sourceforge)-->
    <dependency>
      <groupId>com.jamonapi</groupId>
      <artifactId>jamon</artifactId>
      <version>2.7</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>javax.mail</groupId>
      <artifactId>mail</artifactId>
      <version>1.4.3</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>javassist</groupId>
      <artifactId>javassist</artifactId>
      <version>3.9.0.GA</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>jaxen</groupId>
      <artifactId>jaxen</artifactId>
      <version>1.1</version>
      <scope>provided</scope>
    </dependency>
    <!-- This lib must be added to your repository -->
    <dependency>
      <groupId>org.play.jj</groupId>
      <artifactId>imaging</artifactId>
      <version>1.1</version>
      <scope>provided</scope>
    </dependency>
    <!-- This lib must be added to your repository -->
    <dependency>
      <groupId>org.play.jj</groupId>
      <artifactId>simple-captcha</artifactId>
      <version>1.1</version>
      <scope>provided</scope>
    </dependency>
    <!-- This lib must be added to your repository -->
    <dependency>
      <groupId>org.play.jj</groupId>
      <artifactId>textile</artifactId>
      <version>1.1</version>
      <scope>provided</scope>
    </dependency>
    <!-- This lib must be added to your repository -->
    <dependency>
      <groupId>org.play.jj</groupId>
      <artifactId>wikitext</artifactId>
      <version>1.1</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>joda-time</groupId>
      <artifactId>joda-time</artifactId>
      <version>1.6</version>
      <scope>provided</scope>
    </dependency>
    <!-- This lib must be added to your repository (comes from Sourceforge)-->
    <dependency>
      <groupId>jregex</groupId>
      <artifactId>jregex</artifactId>
      <version>1.2_01</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>net.sf.jsr107cache</groupId>
      <artifactId>jsr107cache</artifactId>
      <version>1.0</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>javax.transaction</groupId>
      <artifactId>jta</artifactId>
      <version>1.1</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.8.1</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>log4j</groupId>
      <artifactId>log4j</artifactId>
      <version>1.2.16</version>
      <scope>provided</scope>
    </dependency>
    <!-- This lib must be added to your repository -->
    <dependency>
      <groupId>net.spy</groupId>
      <artifactId>memcached</artifactId>
      <version>2.4.2</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>5.1.13</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>org.jboss.netty</groupId>
      <artifactId>netty</artifactId>
      <version>3.2.2.Final</version>
      <scope>provided</scope>
    </dependency>
    <!-- This lib must be added to your repository -->
    <dependency>
      <groupId>org.play</groupId>
      <artifactId>org.eclipse.jdt.core</artifactId>
      <version>3.6.0</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>net.sf.oval</groupId>
      <artifactId>oval</artifactId>
      <version>1.50</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>org.apache.geronimo.specs</groupId>
      <artifactId>geronimo-servlet_2.5_spec</artifactId>
      <version>1.2</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>oauth.signpost</groupId>
      <artifactId>signpost-core</artifactId>
      <version>1.2</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-api</artifactId>
      <version>1.6.1</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-log4j12</artifactId>
      <version>1.6.1</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>org.yaml</groupId>
      <artifactId>snakeyaml</artifactId>
      <version>1.6</version>
      <scope>provided</scope>
    </dependency>
    
    <!-- Play! framework dependency -->
    <dependency>
      <groupId>org.play</groupId>
      <artifactId>play</artifactId>
      <version>1.1</version>
    </dependency>
    
    <dependency>
      <groupId>org.play</groupId>
      <artifactId>play-runtime</artifactId>
      <version>1.1</version>
      <type>zip</type>
    </dependency>
  </dependencies>
  
  <build>
    <sourceDirectory>app</sourceDirectory>
    <pluginManagement>
      <plugins>
        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-war-plugin</artifactId>
          <version>2.1.1</version>
          <configuration>
            <failOnMissingWebXml>false</failOnMissingWebXml>
          </configuration>
        </plugin>

        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-dependency-plugin</artifactId>
          <version>2.1</version>
          <executions>
            <execution>
              <id>default-cli</id>
              <configuration>
                <includeClassifiers>,sources</includeClassifiers>
                <outputDirectory>lib/</outputDirectory>
                <excludeScope>provided</excludeScope>
                <!-- To download sources jars without failing -->
                <failOnMissingClassifierArtifact>false</failOnMissingClassifierArtifact>
                <excludeArtifactIds>play-runtime,play</excludeArtifactIds>
              </configuration>
            </execution>
            <execution>
              <id>packaging</id>
              <phase>package</phase>
              <goals>
                <goal>copy-dependencies</goal>
              </goals>
              <configuration>
                <includeArtifactIds>play-runtime</includeArtifactIds>
              </configuration>
            </execution>
          </executions>
        </plugin>

        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-antrun-plugin</artifactId>
          <version>1.6</version>
          <executions>
            <execution>
              <phase>package</phase>
              <configuration>
                <target>
                  <property name="maven.project.artifactId" value="${project.artifactId}" />
                  <property name="maven.project.version" value="${project.version}" />
                  <property name="maven.project.play-runtime" value="play-runtime-${play.version}" />

                  <property name="play.runtime.path" value="${basedir}/target/dependency/${maven.project.play-runtime}" />
                  <property name="play.runtime.file" value="${basedir}/target/dependency/${maven.project.play-runtime}.zip" />
                  <property name="play.runtime.unzip.path" value="${basedir}/target/dependency" />

                  <!-- Check zipped Play! runtime is present. Build fails if not present -->
                  <available file="${play.runtime.file}" property="play.runtime.present" />
                  <echo message="Is Play! runtime present : ${play.runtime.present}" />

                  <fail message="Error : Play! runtime could not be found at : ${play.runtime.file}">
                    <condition>
                      <not>
                        <isset property="play.runtime.present" />
                      </not>
                    </condition>
                  </fail>

                  <!-- Delete existing Play! runtime -->
                  <echo message="Deleting any existing unzipped Play! runtime ..." />
                  <delete dir="play.runtime.unzip.path" failonerror="false" verbose="true" />

                  <!-- Unzip Play! runtime -->
                  <echo message="Unzipping Play! runtime ..." />
                  <unzip src="${play.runtime.file}" dest="${play.runtime.unzip.path}" />
                  <echo message="Play! runtime unzipped successfully." />
                  <chmod dir="${play.runtime.path}" perm="ugo+x" includes="play" />

                  <!-- launch play mvn:up to retrieve libs in /lib folder -->
                  <condition property="playExtension" value=".bat">
                    <and>
                      <os family="windows" />
                    </and>
                  </condition>
                  <condition property="playExtension" value="">
                    <and>
                      <os family="unix" />
                    </and>
                  </condition>
                  <exec executable="${play.runtime.unzip.path}/${maven.project.play-runtime}/play${playExtension}">
                    <arg value="mvn:up" />
                  </exec>

                  <!-- Launch Play war command -->
                  <condition property="playExtension" value=".bat">
                    <and>
                      <os family="windows" />
                    </and>
                  </condition>
                  <condition property="playExtension" value="">
                    <and>
                      <os family="unix" />
                    </and>
                  </condition>
                  <exec executable="${play.runtime.unzip.path}/${maven.project.play-runtime}/play${playExtension}">
                    <arg value="war" />
                    <arg value="${basedir}" />
                    <arg value="-o" />
                    <arg value="${basedir}/target/${maven.project.artifactId}-${maven.project.version}" />
                    <arg value="--zip" />
                  </exec>
                </target>
              </configuration>
              <goals>
                <goal>run</goal>
              </goals>
            </execution>
          </executions>
        </plugin>

        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-clean-plugin</artifactId>
          <version>2.4.1</version>
          <configuration>
            <filesets>
              <fileset>
                <directory>${project.basedir}/lib</directory>
                <includes>
                  <include>**/*.jar</include>
                  <include>**/*.zip</include>
                </includes>
                <followSymlinks>false</followSymlinks>
              </fileset>
            </filesets>
          </configuration>
        </plugin>
        
        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>2.3.1</version>
          <configuration>
            <source>1.5</source>
            <target>1.5</target>
          </configuration>
        </plugin>

      </plugins>
    </pluginManagement>

  </build>
  
</project>

8 Responses to “Play! Framework / Intégration Continue : retour d’expérience”

  1. Bonjour,

    Est ce que le fichier de dependences de Play pourrait ^tre inclus dans le package officiel?

  2. [...] Ce billet était mentionné sur Twitter par Benoit Courtine et nicolasleroux, Jean-Philippe Briend. Jean-Philippe Briend a dit: Mon retour d'expérience Play! / Intégration Continue : http://bit.ly/fKIlcM [...]

  3. Très bon article, m’a permis d’appréhender ce qui était nécessaire pour “mavenizé” un développement avec Play!

    Merci :-)

  4. nicogiard dit :

    Bravo Jean-Philippe pour tout ce travail !

    Par contre il faut que tu nous partage le pom.xml avec les dependancies, qu’on perde pas notre temps nous aussi :p

  5. Il pourrait etre inclus, mais il y a quelques librairies qui n’existent pas sur les repo Maven officiels. Il faut donc les charger manuellement dans son Nexus.

    Je te fais une Pull request sur github.

  6. [...] Play! Framework / Intégration Continue : retour d’expérience déc 16 [...]

  7. Alain Laniel dit :

    Bonjour Jean-Philippe,
    Je sais que cet article date déjà d’un an, mais je dois faire une intégration similaire chez un de mes clients. Avant de me lancer dans l’aventure, je me demandais si l’information contenue dans ton article était encore pertinente aujourd’hui et bien sûr si de nouvelles fonctionnalités de la version 1.2.4 pouvaient modifier les étapes décrites plus haut.

    Merci et bonne journée

  8. Le plus gros changement est la gestion des dépendances par Ivy. Par contre, ça ne simplifie pas l’intégration à Maven.
    Je pense que la plupart des scripts de cet article sont toujours d’actualité.
    Bien sûr, il faudrait mettre à jour le pom de Play pour refléter les changements de version des librairies du framework, mais ça ne devrait pas poser de problème.

Leave a Reply


Creative Commons License
Blog Infin-It par Infin-It est mis à disposition selon les termes de la licence Creative Commons Paternité-Pas d'Utilisation Commerciale 2.0 France.