intégration continue php avec jenkins ci

87

Upload: hugo-hamon

Post on 12-Nov-2014

6.315 views

Category:

Technology


1 download

DESCRIPTION

Comment assurer le suivi qualite du code source d'une application web? Ce n'est pas une tache aisée ! C’est d’autant plus vrai que PHP est encore considéré aujourd'hui comme un langage peu professionnel. PHP est pourtant un langage dont l'outillage n'a rien a envier a l'ensemble de ses concurrents. L'objectif de cette conférence est de présenter les bonnes pratiques à adopter ainsi que les différents outils a mettre en oeuvre afin de contrôler la qualité d'un projet PHP au quotidien. Un focus particulier sera porté sur la plateforme d'intégration continue Jenkins, les tests unitaires ou bien encore la récupération et l'interprétation des métriques collectées.

TRANSCRIPT

Page 1: Intégration Continue PHP avec Jenkins CI
Page 2: Intégration Continue PHP avec Jenkins CI

Comment surveiller la qualité de vos projets PHP au quotidien ?

Page 3: Intégration Continue PHP avec Jenkins CI

« L'intégration continue est un ensemble de pratiques qui consistent à véri"er à chaque

changement du code source que le résultat

des modi"cations ne produit pas de

régression de l'application en cours de

développement » Wikipedia

Page 4: Intégration Continue PHP avec Jenkins CI

Quels avantages ?

Page 5: Intégration Continue PHP avec Jenkins CI

Quelles pratiques au quotidien ?

Page 6: Intégration Continue PHP avec Jenkins CI

q  Maintenir un dépôt unique de code versionné

q  Tous les développeurs committent quotidiennement

q  Automatiser les compilations (builds)

q  Tout commit doit compiler le tronc du code versionné

q  Maintenir une compilation courte en permanence

q  Rendre disponible le résultat du build à tout le monde

q  Automatiser le déploiement

Page 7: Intégration Continue PHP avec Jenkins CI

Alice

Bob

Carlos

SCM Server

CI Server

Build Successful

Page 8: Intégration Continue PHP avec Jenkins CI

Alice

Bob

Carlos

SCM Server

CI Server

Build Failed

Alerter l’équipe

Page 9: Intégration Continue PHP avec Jenkins CI

Alice

Bob

Carlos

SCM Server

CI Server

Build Successful

Page 10: Intégration Continue PHP avec Jenkins CI

Quelles PIC sur le marché ?

Page 11: Intégration Continue PHP avec Jenkins CI
Page 12: Intégration Continue PHP avec Jenkins CI

Mettre en œuvre une PIC pour PHP

Page 13: Intégration Continue PHP avec Jenkins CI

q  Exécution de la suite de tests unitaires (PHPUnit)

q  Génération du rapport de couverture de code (PHPUnit)

q  Génération de la documentation d’API (PHPDocumentor)

q  Génération du rapport des dépendances (PDepend)

q  Analyse statique du code source (PMD)

q  Détection des violations de codage (PHP_CodeSniffer)

q  Détection du code dupliqué (PHPCPD)

q  Génération du navigateur de code (PHP Code Browser)

Page 14: Intégration Continue PHP avec Jenkins CI
Page 15: Intégration Continue PHP avec Jenkins CI

q  Hudson rebaptisé Jenkins en février 2011

q  Ecrit en Java

q  Exécute des tâches Ant, Maven, Shell et Windows

q  +300 plugins

q  Analyse des rapports de compilation

q  Génération de statistiques et de graphiques (métriques)

Page 16: Intégration Continue PHP avec Jenkins CI
Page 17: Intégration Continue PHP avec Jenkins CI

http://jenkins-ci.org

Page 18: Intégration Continue PHP avec Jenkins CI

$ java –jar jenkins.war

Page 19: Intégration Continue PHP avec Jenkins CI

http://localhost:8080

Page 20: Intégration Continue PHP avec Jenkins CI

q  XDebug

q  PDepend

q  PHP Mess Detector

q  PHP CodeSniffer

q  PHPUnit 3.6.x

q  PHPCPD

q  PHP Documentor

q  PHP CodeBrowser

Page 21: Intégration Continue PHP avec Jenkins CI

$ pecl install xdebug $ pear channel-discover pear.pdepend.org $ pear channel-discover pear.phpmd.org $ pear channel-discover pear.phpunit.de $ pear channel-discover components.ez.no $ pear channel-discover pear.symfony-project.com $ pear channel-discover pear.phing.info $ pear install phing/phing $ pear install pdepend/PHP_Depend-beta $ pear install phpmd/PHP_PMD-alpha $ pear install phpunit/phpcpd $ pear install PHPDocumentor $ pear install PHP_CodeSniffer $ pear install --alldeps phpunit/PHP_CodeBrowser-alpha $ pear install --alldeps phpunit/PHPUnit

Page 22: Intégration Continue PHP avec Jenkins CI

Plugins Jenkins

Page 23: Intégration Continue PHP avec Jenkins CI

q  Subversion

q  Git

q  Checkstyle

q  Dry

q  HTML Publisher

q  Green Balls

q  JDepend

q  PMD

q  Violations

q  xUnit

q  Clover

Page 24: Intégration Continue PHP avec Jenkins CI

Démarrer un projet

Page 25: Intégration Continue PHP avec Jenkins CI

Projet free-style

Page 26: Intégration Continue PHP avec Jenkins CI

Con"guration du projet

Page 27: Intégration Continue PHP avec Jenkins CI

Con"guration du dépôt Subversion

Page 28: Intégration Continue PHP avec Jenkins CI

Dé"nition des droits d’accès au SVN

Page 29: Intégration Continue PHP avec Jenkins CI

Con"guration du dépôt Git

Page 30: Intégration Continue PHP avec Jenkins CI

Con"guration des builds

Page 31: Intégration Continue PHP avec Jenkins CI

Exécution et contrôle du build

Page 32: Intégration Continue PHP avec Jenkins CI

Exécution et contrôle du build

Page 33: Intégration Continue PHP avec Jenkins CI

Phing

Page 34: Intégration Continue PHP avec Jenkins CI

q  Phing est un portage de Ant en PHP

q  Outil d’automatisation de tâches

q  Phing exécute des tâches à la suite

q  Les tâches sont décrites dans un "chier build.xml

q  Supporte les dépendances entre les tâches

q  Tâches prédé"nies pour PHPUnit, Code Sniffer, PMD…

Page 35: Intégration Continue PHP avec Jenkins CI

<?xml version="1.0" encoding="UTF-8"?> <project name="Syndication Component" basedir="." default="main"> <property name="builddir" value="${ws}/build" /> <property name="srcdir" value="${project.basedir}" override="true" /> <property name="package" value="Syndication" override="true" /> <target name="clean" description="Clean the build environment"> <delete dir="${builddir}" /> <delete dir="generatedJUnitFiles" /> </target> <target name="prepare" depends="clean" description="Clean the build environment"> <mkdir dir="${builddir}" /> <mkdir dir="${builddir}/logs" /> <mkdir dir="${builddir}/logs/coverage" /> <mkdir dir="${builddir}/docs" /> <mkdir dir="${builddir}/browser" /> </target> <target name="build" depends="prepare" description="Build the project"> <!-- build target commands here --> </target> </project>

Page 36: Intégration Continue PHP avec Jenkins CI

phing –f $WORKSPACE/build.xml build –Dws=$WORKSPACE

Page 37: Intégration Continue PHP avec Jenkins CI

PHPUnit

http://phpunit.de/

Page 38: Intégration Continue PHP avec Jenkins CI

q  Exécuter les tests unitaires

q  Générer un rapport JUnit

q  Générer un rapport Clover XML

q  Générer un rapport de couverture HTML

Page 39: Intégration Continue PHP avec Jenkins CI

<?xml version="1.0" encoding="UTF-8"?> <phpunit backupGlobals="false" backupStaticAttributes="false" colors="true" convertErrorsToExceptions="true" convertNoticesToExceptions="true" convertWarningsToExceptions="true" processIsolation="true" stopOnFailure="false" syntaxCheck="false" bootstrap="src/autoload.php"> <testsuites> <testsuite name="Syndication Component Test Suite"> <directory>./tests/Syndication/</directory> </testsuite> </testsuites> <filter> <whitelist> <directory>./src/Syndication/</directory> </whitelist> </filter> </phpunit>

Page 40: Intégration Continue PHP avec Jenkins CI

<?xml version="1.0" encoding="UTF-8"?> <project name="Syndication Component" basedir="." default="main"> <!-- ... --> <target name="build" depends="prepare" description="Building the project"> <phingcall target="phpunit" /> </target> <target name="phpunit" description="Running unit tests and coverage analysis"> <exec command="phpunit --log-junit ${builddir}/logs/phpunit.xml --coverage-clover ${builddir}/logs/coverage/clover.xml --coverage-html ${builddir}/logs/coverage/ ${ws}/tests" /> </target> </project>

Page 41: Intégration Continue PHP avec Jenkins CI

Con"gurer la suite de tests unitaires

Page 42: Intégration Continue PHP avec Jenkins CI

Con"gurer la couverture de code

Page 43: Intégration Continue PHP avec Jenkins CI

Analyse de la couverture de code

Page 44: Intégration Continue PHP avec Jenkins CI

Analyse des rapports de tests unitaires

Page 45: Intégration Continue PHP avec Jenkins CI

Analyse des rapports de tests unitaires

Page 46: Intégration Continue PHP avec Jenkins CI

Publication de la couverture de code

Page 47: Intégration Continue PHP avec Jenkins CI

Publication de la couverture de code

Page 48: Intégration Continue PHP avec Jenkins CI

PHPDocumentor

http://www.phpdoc.org/

Page 49: Intégration Continue PHP avec Jenkins CI

Générer la documentation d’API

Page 50: Intégration Continue PHP avec Jenkins CI

<project name="Syndication Component" basedir="." default="main"> <target name="build" depends="prepare"> <phingcall target="phpunit" /> <phingcall target="phpdoc" /> </target> <!-- Generating API Documentation --> <target name="phpdoc" description="Generating api doc"> <phpdoc title="Syndication API Documentation" destdir="${builddir}/docs" sourcecode="true" parseprivate="true" output="HTML:Smarty:PHP"> <fileset dir="./src"> <include name="**/*.php" /> </fileset> </phpdoc> </target> </project>

Page 51: Intégration Continue PHP avec Jenkins CI

Publication de la documentation d’API

Page 52: Intégration Continue PHP avec Jenkins CI

Publication de la documentation d’API

Page 53: Intégration Continue PHP avec Jenkins CI

PHPCPD Copy Paste Detector

https://github.com/sebastianbergmann/phpcpd

Page 54: Intégration Continue PHP avec Jenkins CI

Rechercher les duplications de code

Page 55: Intégration Continue PHP avec Jenkins CI

<?xml version="1.0" encoding="UTF-8"?> <project name="Syndication Component" basedir="." default="main"> <!-- ... --> <target name="build" depends="prepare"> <phingcall target="phpunit" /> <phingcall target="phpdoc" /> <phingcall target="phpcpd" /> </target> <!-- Detecting duplicated code --> <target name="phpcpd" description="Detecting duplicated code"> <exec command="phpcpd --min-lines 5 --min-tokens 5 --log-pmd ${builddir}/logs/pmd-cpd.xml src/" /> </target> </project>

Page 56: Intégration Continue PHP avec Jenkins CI
Page 57: Intégration Continue PHP avec Jenkins CI
Page 58: Intégration Continue PHP avec Jenkins CI

Ce graphique montre que le code dupliqué a bien été retiré dans le nouveau commit qui a donné lieu au dernier build.

Le graphique ci-contre montre l’évolution du nombre de tests unitaires réussis au dernier build.

Page 59: Intégration Continue PHP avec Jenkins CI

PHP Depend

http://pdepend.org/

Page 60: Intégration Continue PHP avec Jenkins CI

q  Complexité cyclomatique q  Qualité globale du code q  Nombre de classes / méthodes / fonctions / interfaces q  Nombre d’appels d’une méthode q  Nombre de propriétés / méthodes publiques vs privées q  Nombre de lignes de code en commentaires….

Analyse statique du code

Page 61: Intégration Continue PHP avec Jenkins CI

Analyse statique du code

build/logs/jdepend.xml

Page 62: Intégration Continue PHP avec Jenkins CI

<?xml version="1.0" encoding="UTF-8"?> <project name="Syndication Component" basedir="." default="main"> <!-- ... --> <target name="build" depends="prepare"> <phingcall target="phpunit" /> <phingcall target="phpdoc" /> <phingcall target="phpcpd" /> <phingcall target="pdepend" /> </target> <target name="pdepend" description="Generating JDepend report"> <exec command="pdepend --jdepend-xml=${builddir}/logs/jdepend.xml src/" /> </target> </project>

Page 63: Intégration Continue PHP avec Jenkins CI
Page 64: Intégration Continue PHP avec Jenkins CI

PHP Mess Detector

http://phpmd.org/

Page 65: Intégration Continue PHP avec Jenkins CI

q  PHP Mess Detector est un portage en PHP de PMD (Java)

q  Recherche de bugs potentiels

q  Recherche de code mort (ie: méthodes non appelées)

q  Code non optimisé

q  Expressions trop complexes…

Analyse statique du code

Page 66: Intégration Continue PHP avec Jenkins CI
Page 67: Intégration Continue PHP avec Jenkins CI

<?xml version="1.0" encoding="UTF-8"?> <project name="Syndication Component" basedir="." default="main"> <!-- ... --> <target name="build" depends="prepare"> <phingcall target="phpunit" /> <phingcall target="phpdoc" /> <phingcall target="phpcpd" /> <phingcall target="pdepend" /> <phingcall target="pmd" /> </target> <target name="phpmd" description="Generating PHPMD report"> <exec command="phpmd src/ xml codesize,unusedcode --reportfile ${builddir}/logs/pmd.xml" /> </target> </project>

Page 68: Intégration Continue PHP avec Jenkins CI
Page 69: Intégration Continue PHP avec Jenkins CI

PHP Code Sniffer http://pear.php.net/manual/en/package.php.php-codesniffer.php

Page 70: Intégration Continue PHP avec Jenkins CI

q  Analyse des violations de codage

q  Nombreuses règles par défaut

q  Standards prédé"nis : PEAR, Zend, Squiz, PHPCS…

q  Possibilité d’ajouter des règles supplémentaires

Page 71: Intégration Continue PHP avec Jenkins CI

$ # Looking for the PEAR PHP directory $ pear config-show | grep php_dir $ # Move to the CodeSniffer standards folder $ cd /path/to/pear/PHP/CodeSniffer/Standards $ # Checkout the Symfony2 CodeSniffer standard from Github $ git clone git://github.com/opensky/Symfony2-coding-standard.git Symfony2 $ # Eventually, set Symfony2 as your default CodeSniffer standard $ phpcs --config-set default_standard Symfony2

Installation du standard Symfony2

Page 72: Intégration Continue PHP avec Jenkins CI

Installation du standard Symfony2

build/logs/checkstyle.xml

Page 73: Intégration Continue PHP avec Jenkins CI

<?xml version="1.0" encoding="UTF-8"?> <project name="Syndication Component" basedir="." default="main"> <target name="build" depends="prepare"> <phingcall target="phpunit" /> <phingcall target="phpdoc" /> <phingcall target="phpcpd" /> <phingcall target="pdepend" /> <phingcall target="phpmd" /> <phingcall target="checkstyle" /> </target> <target name="checkstyle" description="Looking for violations"> <exec command="phpcs --standard=Symfony2 --report=checkstyle ${project.basedir}/src > ${builddir}/logs/checkstyle.xml" escape="false" /> </target> </project>

Page 74: Intégration Continue PHP avec Jenkins CI
Page 75: Intégration Continue PHP avec Jenkins CI
Page 76: Intégration Continue PHP avec Jenkins CI

PHP Code Browser https://github.com/mayflower/PHP_CodeBrowser

Page 77: Intégration Continue PHP avec Jenkins CI

build/browser

Page 78: Intégration Continue PHP avec Jenkins CI

<?xml version="1.0" encoding="UTF-8"?> <project name="Syndication Component" basedir="." default="main"> <!-- ... --> <target name="build" depends="prepare"> <phingcall target="phpunit" /> <phingcall target="phpdoc" /> <phingcall target="phpcpd" /> <phingcall target="pdepend" /> <phingcall target="phpmd" /> <phingcall target="checkstyle" /> <phingcall target="phpcb" /> </target> <target name="phpcb" description="Generating code browser..."> <exec command="phpcb --log ${builddir}/logs --source ${project.basedir}/src --output ${builddir}/browser" /> </target> </project>

Page 79: Intégration Continue PHP avec Jenkins CI
Page 80: Intégration Continue PHP avec Jenkins CI

Prévenir plutôt que guérir!

Page 81: Intégration Continue PHP avec Jenkins CI

q  Emails

q  Twitter

q  Jabber

q  RSS

q  SMS

q  …

Page 82: Intégration Continue PHP avec Jenkins CI

Comment industrialiser la PIC

d’un projet PHP dans Jenkins ?

Page 83: Intégration Continue PHP avec Jenkins CI

http://jenkins-php.org/

Page 84: Intégration Continue PHP avec Jenkins CI

Aller plus loin avec Jenkins

Page 85: Intégration Continue PHP avec Jenkins CI

q  Générer des archives PHAR, PEAR, TAR ou ZIP

q  Automatiser le déploiement des builds stables

q  Faciliter les audits de code

q  Intégration avec un bug tracker (Trac, Redmine, Jira)

q  Exécution de tests Sélénium / Fitness

q  …

Page 86: Intégration Continue PHP avec Jenkins CI

Merci !

Page 87: Intégration Continue PHP avec Jenkins CI

Ques%ons?  

92-98, boulevard Victor Hugo

92 115 Clichy Cedex

[email protected] (+33 (0)1 40 99 82 11)

sensiolabs.com - symfony.com – trainings.sensiolabs.com