Upload
hugo-hamon
View
24.376
Download
4
Embed Size (px)
Citation preview
INTÉGRATION CONTINUE D’UN PROJET PHP AVEC JENKINS.
Hugo Hamon – Confoo 2011 – Montreal, Canada
http://joind.in/talk/view/2863
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
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 »
Avantages…
Détecter les problèmes le plus tôt possible…
Avantages…
… a"n d’alerter l’équipe le plus vite possible !
Avantages…
Générer des compilations régulièrement…
Avantages…
…a"n d’obtenir des versions stables et déployables le plus souvent possible.
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
Workflow de l’Intégration Continue
Alice
Bob
Carlos
SCM Server
CI Server
Build Successful
Workflow de l’Intégration Continue
Alice
Bob
Carlos
SCM Server
CI Server
Build Failed
Alerter l’équipe
Workflow de l’Intégration Continue
Alice
Bob
Carlos
SCM Server
CI Server
Build Successful
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)
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)
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)
Ils utilisent Jenkins CI
Installation
Installation de 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
Installer Jenkins
http://localhost:8080/
Installer les outils PHP
¨ XDebug
¨ PDepend
¨ PHP Mess Detector
¨ PHP CodeSniffer
¨ PHPUnit 3.5.x
¨ PHPCPD
¨ PHP Documentor
¨ PHP CodeBrowser
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
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
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
Nouveau projet
Démarrer un nouveau projet
Initialiser un nouveau projet
¨ Création d’un nouveau « projet free-style »
Initialiser un nouveau projet
¨ Ajout d’une description et suppression des anciens builds
Configuration du dépôt SVN
Subversion Dépôt de code
Dossier local
Préférer les updates au lieu des checkouts
Configuration du dépôt SVN
¨ Dé"nition des droits d’accès au dépôt de code Subversion.
Configuration du dépôt Git
Git
URL du dépôt de code
Branche à construire
Navigateur de code source
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
Exécution et contrôle du build
Build réussi !
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.
Phing
Con"guration de Phing
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…
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
Commande SHELL à exécuter
phing –f $WORKSPACE/build.xml build –Dws=$WORKSPACE
PHPUnit
Con"guration des tests unitaires
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
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>
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>
Configurer la suite de tests unitaires
¨ Analyse des logs JUnit générés par PHPunit
¨ Publication des graphiques sur le tableau de bord
Configurer la couverture de code
¨ Analyse et publication des rapports de couverture de code
Analyse de la couverture de code
Analyse des rapports de tests unitaires
9/9
Analyse des tests unitaires
Publication de la couverture de code
Publication de la couverture de code
PHPDocumentor
Con"guration de PHPDocumentor
Générer la documentation d’API
¨ La PHPDoc est générée dans le dossier build/docs.
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>
Publication de la documentation API
Accès à la doc API
Publication de la documentation API
PHPCPD
Con"guration de PHPCPD
Rechercher les duplications de code
¨ PHPCPD détecte le code dupliqué dans les "chiers
¨ Le rapport est généré au format PMD
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>
Rechercher les duplications de code
Rechercher les duplications de code
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.
PHPDepend
Con"guration de PHPDepend
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….
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>
Publier les dépendances
PMD
Con"guration de PHP Mess Detector
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…
Configurer PHP Mess Detector
Fichier de log généré par PMD
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>
Publier les rapports PMD
PHP_CodeSniffer
Con"guration de PHP_CodeSniffer
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
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
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>
Publier le rapport des violations
Publier le rapport des violations
PHP Code Browser
Con"guration de PHP Code Browser
Générer le navigateur de code
¨ La navigateur est généré dans le dossier build/browser.
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>
Publier le navigateur de code
Accès au navigateur de code
Publier le navigateur de code
Prévenir et guérir au plus vite
Con"gurer des alertes
Moyens de communication
¨ Emails
¨ Jabber
¨ RSS
¨ …
Alerter l’équipe par e-mail
¨ Saisie des adresses email des équipiers du projet
¨ Possibilité d’alerter les responsables d’un build en échec
Industrialisation
Industrialiser l’intégration continue
d’un projet PHP dans 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
Pour aller plus loin
Aller plus loin…
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
Merci !
Sensio S.A. 92-98, boulevard Victor Hugo
92 115 Clichy Cedex FRANCE
www.sensiolabs.com - www.symfony.com - trainings.sensiolabs.com
Questions!