86
INTÉGRATION CONTINUE D’UN PROJET PHP AVEC JENKINS. Hugo Hamon – Confoo 2011 – Montreal, Canada http://joind.in/talk/view/2863

Intégration continue des projets PHP avec Jenkins

Embed Size (px)

Citation preview

Page 1: Intégration continue des projets PHP avec Jenkins

INTÉGRATION CONTINUE D’UN PROJET PHP AVEC JENKINS.

Hugo Hamon – Confoo 2011 – Montreal, Canada

http://joind.in/talk/view/2863

Page 2: Intégration continue des projets PHP avec Jenkins

Qui suis-je ?

v  Hugo HAMON (@hhamon)

v  Responsable des formations v  Secrétaire de l’AFUP (2010)

v  Contributeur au projet Symfony

v  Coauteur & contributeur à des ouvrages Eyrolles

Page 3: Intégration continue des projets PHP avec Jenkins

Introduction…

« 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 »

Page 4: Intégration continue des projets PHP avec Jenkins

Avantages…

Détecter les problèmes le plus tôt possible…

Page 5: Intégration continue des projets PHP avec Jenkins

Avantages…

… a"n d’alerter l’équipe le plus vite possible !

Page 6: Intégration continue des projets PHP avec Jenkins

Avantages…

Générer des compilations régulièrement…

Page 7: Intégration continue des projets PHP avec Jenkins

Avantages…

…a"n d’obtenir des versions stables et déployables le plus souvent possible.

Page 8: Intégration continue des projets PHP avec Jenkins

Pratiques quotidiennes…

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 9: Intégration continue des projets PHP avec Jenkins

Workflow de l’Intégration Continue

Alice

Bob

Carlos

SCM Server

CI Server

Build Successful

Page 10: Intégration continue des projets PHP avec Jenkins

Workflow de l’Intégration Continue

Alice

Bob

Carlos

SCM Server

CI Server

Build Failed

Alerter l’équipe

Page 11: Intégration continue des projets PHP avec Jenkins

Workflow de l’Intégration Continue

Alice

Bob

Carlos

SCM Server

CI Server

Build Successful

Page 12: Intégration continue des projets PHP avec Jenkins

Intégration Continue PHP

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 13: Intégration continue des projets PHP avec Jenkins

Marché de l’Intégration Continue

¨  Maven (Java, Open Source)

¨  CruiseControl (Java, Open Source)

¨  Bamboo (Java, Commercial)

¨  Jenkins (Java, Open Source)

¨  Sonar (Java, Open Source)

¨  Xinc (PHP, Open Source)

Page 14: Intégration continue des projets PHP avec Jenkins

Jenkins CI

¨  Hudson rebaptisé Jenkins en février 2011

¨  Ecrit en Java

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

¨  +300 plugins

¨  Analyse des rapports de compilation

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

Page 15: Intégration continue des projets PHP avec Jenkins

Ils utilisent Jenkins CI

Page 16: Intégration continue des projets PHP avec Jenkins

Installation

Installation de Jenkins

Page 17: Intégration continue des projets PHP avec Jenkins

Installer Jenkins CI

¨  Télécharger le "chier jenkins.war sur jenkins-ci.org

¨  Exécuter le "chier jenkins.war

http://mirrors.jenkins-ci.org/war/latest/jenkins.war

$ java –jar jenkins.war

Page 18: Intégration continue des projets PHP avec Jenkins

Installer Jenkins

http://localhost:8080/

Page 19: Intégration continue des projets PHP avec Jenkins

Installer les outils PHP

¨  XDebug

¨  PDepend

¨  PHP Mess Detector

¨  PHP CodeSniffer

¨  PHPUnit 3.5.x

¨  PHPCPD

¨  PHP Documentor

¨  PHP CodeBrowser

Page 20: Intégration continue des projets PHP avec Jenkins

Installer les outils PHP

$ 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 21: Intégration continue des projets PHP avec Jenkins

Installer les plugins Jenkins

¨  Subversion pour l’intégration des dépôts SVN

¨  Git pour l’intégration des dépôts Git

¨  Checkstyle pour l’analyse des rapports PHP_CodeSniffer

¨  Dry pour l’analyser des rapports PHPCPD

¨  HTML Publisher pour la publication des logs de couverture de code

¨  Green Balls pour avoir des billes vertes au lieu des bleues J

Page 22: Intégration continue des projets PHP avec Jenkins

Installer les plugins Jenkins

¨  JDepend pour l’analyse des rapports PHP_Depend

¨  PMD pour le traitement des rapports PHP Mess Detector

¨  Violations pour le traitement de rapports variés

¨  xUnit pour le traitement des logs de tests PHPUnit

¨  Clover pour le traitement des logs de couverture de code de PHPUnit

Page 23: Intégration continue des projets PHP avec Jenkins

Nouveau projet

Démarrer un nouveau projet

Page 24: Intégration continue des projets PHP avec Jenkins

Initialiser un nouveau projet

¨  Création d’un nouveau « projet free-style »

Page 25: Intégration continue des projets PHP avec Jenkins

Initialiser un nouveau projet

¨  Ajout d’une description et suppression des anciens builds

Page 26: Intégration continue des projets PHP avec Jenkins

Configuration du dépôt SVN

Subversion Dépôt de code

Dossier local

Préférer les updates au lieu des checkouts

Page 27: Intégration continue des projets PHP avec Jenkins

Configuration du dépôt SVN

¨  Dé"nition des droits d’accès au dépôt de code Subversion.

Page 28: Intégration continue des projets PHP avec Jenkins

Configuration du dépôt Git

Git

URL du dépôt de code

Branche à construire

Navigateur de code source

Page 29: Intégration continue des projets PHP avec Jenkins

Configuration du déclenchement

¨  Le build est déclenché toutes les 5 minutes.

¨  Un nouveau build est déclenché si des commits ont eu lieu

Syntaxe de crontab

Page 30: Intégration continue des projets PHP avec Jenkins

Exécution et contrôle du build

Build réussi !

Page 31: Intégration continue des projets PHP avec Jenkins

Exécution et contrôle du build

¨  La page d’accueil affiche la tendance de chaque projet…

¨  … et l’état du dernier build effectué sur chaque projet.

Page 32: Intégration continue des projets PHP avec Jenkins

Phing

Con"guration de Phing

Page 33: Intégration continue des projets PHP avec Jenkins

Configuration de Phing

¨  Phing est un portage de Ant en PHP

¨  Outil d’automatisation de tâches

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

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

¨  Supporte les dépendances entre les tâches

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

Page 34: Intégration continue des projets PHP avec Jenkins

Configuration de Phing (build.xml) <?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>

Nettoyage

Préparation

Build

${ws} est une variable perso

Page 35: Intégration continue des projets PHP avec Jenkins

Commande SHELL à exécuter

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

Page 36: Intégration continue des projets PHP avec Jenkins

PHPUnit

Con"guration des tests unitaires

Page 37: Intégration continue des projets PHP avec Jenkins

Configurer la suite de tests unitaires

¨  Con"gurer et exécuter la suite de tests unitaires

¨  Génération du rapport de la suite au format JUnit

¨  Génération du rapport XML de couverture de code (Clover)

¨  Génération du rapport HTML de couverture de code

Page 38: Intégration continue des projets PHP avec Jenkins

PHPUnit – phpunit.xml

<?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 39: Intégration continue des projets PHP avec Jenkins

Configurer la suite de tests unitaires

<?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 40: Intégration continue des projets PHP avec Jenkins

Configurer la suite de tests unitaires

¨  Analyse des logs JUnit générés par PHPunit

¨  Publication des graphiques sur le tableau de bord

Page 41: Intégration continue des projets PHP avec Jenkins

Configurer la couverture de code

¨  Analyse et publication des rapports de couverture de code

Page 42: Intégration continue des projets PHP avec Jenkins

Analyse de la couverture de code

Page 43: Intégration continue des projets PHP avec Jenkins

Analyse des rapports de tests unitaires

9/9

Page 44: Intégration continue des projets PHP avec Jenkins

Analyse des tests unitaires

Page 45: Intégration continue des projets PHP avec Jenkins

Publication de la couverture de code

Page 46: Intégration continue des projets PHP avec Jenkins

Publication de la couverture de code

Page 47: Intégration continue des projets PHP avec Jenkins

PHPDocumentor

Con"guration de PHPDocumentor

Page 48: Intégration continue des projets PHP avec Jenkins

Générer la documentation d’API

¨  La PHPDoc est générée dans le dossier build/docs.

Page 49: Intégration continue des projets PHP avec Jenkins

Générer la documentation d’API

<project name="Syndication Component" basedir="." default="main"> <!-- ... --> <target name="build" depends="prepare" description="Building the project"> <phingcall target="phpunit" /> <phingcall target="phpdoc" /> </target> <!-- Generating API Documentation --> <target name="phpdoc" description="Generating api documentation..." > <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 50: Intégration continue des projets PHP avec Jenkins

Publication de la documentation API

Accès à la doc API

Page 51: Intégration continue des projets PHP avec Jenkins

Publication de la documentation API

Page 52: Intégration continue des projets PHP avec Jenkins

PHPCPD

Con"guration de PHPCPD

Page 53: Intégration continue des projets PHP avec Jenkins

Rechercher les duplications de code

¨  PHPCPD détecte le code dupliqué dans les "chiers

¨  Le rapport est généré au format PMD

Page 54: Intégration continue des projets PHP avec Jenkins

Rechercher les duplications de code

<?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" /> <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 55: Intégration continue des projets PHP avec Jenkins

Rechercher les duplications de code

Page 56: Intégration continue des projets PHP avec Jenkins

Rechercher les duplications de code

Page 57: Intégration continue des projets PHP avec Jenkins

Rechercher les duplications de code

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 58: Intégration continue des projets PHP avec Jenkins

PHPDepend

Con"guration de PHPDepend

Page 59: Intégration continue des projets PHP avec Jenkins

Déterminer les dépendances

¨  PDepend est un portage en PHP de JDepend (Java) ¨  Analyse statistique du code

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

Page 60: Intégration continue des projets PHP avec Jenkins

Déterminer les dépendances

<?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" /> <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 61: Intégration continue des projets PHP avec Jenkins

Publier les dépendances

Page 62: Intégration continue des projets PHP avec Jenkins

PMD

Con"guration de PHP Mess Detector

Page 63: Intégration continue des projets PHP avec Jenkins

Analyse statistique du code

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

¨  Analyse statistique du code

¨  Recherche de bugs potentiels

¨  Recherche de code mort (méthodes non appelées par exemple)

¨  Code non optimisé

¨  Expressions trop complexes…

Page 64: Intégration continue des projets PHP avec Jenkins

Configurer PHP Mess Detector

Fichier de log généré par PMD

Page 65: Intégration continue des projets PHP avec Jenkins

Configurer PHP Mess Detector

<?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" /> <phingcall target="phpdoc" /> <phingcall target="phpcpd" /> <phingcall target="pdepend" /> <phingcall target="pmd" /> </target> <target name="phpmd" description="Generating PHP Mess Detector report"> <exec command="phpmd src/ xml codesize,unusedcode --reportfile ${builddir}/logs/pmd.xml" /> </target> </project>

Page 66: Intégration continue des projets PHP avec Jenkins

Publier les rapports PMD

Page 67: Intégration continue des projets PHP avec Jenkins

PHP_CodeSniffer

Con"guration de PHP_CodeSniffer

Page 68: Intégration continue des projets PHP avec Jenkins

Analyser les violations de codage

¨  Analyse des conventions de codage avec PHP_CodeSniffer

¨  PHPCS « sniffs » le code à la recherche de violations de règles

¨  Nombreuses règles par défaut

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

¨  Possibilité d’ajouter des règles et standards supplémentaires

Page 69: Intégration continue des projets PHP avec Jenkins

Installation du standard Symfony2

$ # 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

Page 70: Intégration continue des projets PHP avec Jenkins

Configuration de PHP_CodeSniffer

<?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" /> <phingcall target="phpdoc" /> <phingcall target="phpcpd" /> <phingcall target="pdepend" /> <phingcall target="phpmd" /> <phingcall target="checkstyle" /> </target> <target name="checkstyle" description="Looking for codestyle violations..."> <exec command="phpcs --standard=Symfony2 --report=checkstyle ${project.basedir}/src > ${builddir}/logs/checkstyle.xml" escape="false" /> </target> </project>

Page 71: Intégration continue des projets PHP avec Jenkins

Publier le rapport des violations

Page 72: Intégration continue des projets PHP avec Jenkins

Publier le rapport des violations

Page 73: Intégration continue des projets PHP avec Jenkins

PHP Code Browser

Con"guration de PHP Code Browser

Page 74: Intégration continue des projets PHP avec Jenkins

Générer le navigateur de code

¨  La navigateur est généré dans le dossier build/browser.

Page 75: Intégration continue des projets PHP avec Jenkins

Générer le navigateur de code

<?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" /> <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 76: Intégration continue des projets PHP avec Jenkins

Publier le navigateur de code

Accès au navigateur de code

Page 77: Intégration continue des projets PHP avec Jenkins

Publier le navigateur de code

Page 78: Intégration continue des projets PHP avec Jenkins

Prévenir et guérir au plus vite

Con"gurer des alertes

Page 79: Intégration continue des projets PHP avec Jenkins

Moyens de communication

¨  Emails

¨  Twitter

¨  Jabber

¨  RSS

¨  …

Page 80: Intégration continue des projets PHP avec Jenkins

Alerter l’équipe par e-mail

¨  Saisie des adresses email des équipiers du projet

¨  Possibilité d’alerter les responsables d’un build en échec

Page 81: Intégration continue des projets PHP avec Jenkins

Industrialisation

Industrialiser l’intégration continue

d’un projet PHP dans Jenkins ?

Page 82: Intégration continue des projets PHP avec Jenkins

Industrialiser l’intégration d’un projet

¨  Réutilisation d’un template de projet Jenkins

¨  Dites merci à Sebastian Bergmann !

¨  «  PHP Jenkins Template » project

https://github.com/sebastianbergmann/php-jenkins-template

Page 83: Intégration continue des projets PHP avec Jenkins

Pour aller plus loin

Aller plus loin…

Page 84: Intégration continue des projets PHP avec Jenkins

Aller plus loin…

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

¨  Automatiser le déploiement des builds stables

¨  Faciliter les audits de code

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

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

Page 85: Intégration continue des projets PHP avec Jenkins

Merci !

Page 86: Intégration continue des projets PHP avec Jenkins

Sensio S.A. 92-98, boulevard Victor Hugo

92 115 Clichy Cedex FRANCE

www.sensiolabs.com - www.symfony.com - trainings.sensiolabs.com

Questions!