Les dé­ve­lop­peurs con­nais­sent bien les problèmes de l’in­té­gra­tion : un nouveau code a été écrit et le plus gros du travail est main­te­nant fait. Il s’agit à présent d’intégrer le code source dans le projet global et c’est à ce moment que les problèmes sur­vien­nent. Afin d’éviter qu’une ca­tas­trophe se produise au terme de la longue phase de dé­ve­lop­pe­ment, de nom­breuses équipes optent pour la con­ti­nuous in­te­gra­tion (l’in­té­gra­tion continue) : les mo­di­fi­ca­tions sont ainsi intégrées di­rec­te­ment dans le projet au jour le jour et, dans le meilleur des cas, plusieurs fois par jour.

Tout comme la con­ti­nuous delivery, l’in­té­gra­tion continue est avant tout pri­vi­lé­giée dans un en­vi­ron­ne­ment de dé­ve­lop­pe­ment logiciel agile. L’objectif de cette approche moderne est de pro­gres­ser par étapes afin de concevoir le processus de dé­ve­lop­pe­ment plus ef­fi­ca­ce­ment et de pouvoir réagir aux mo­di­fi­ca­tions avec flexi­bi­lité. L’in­té­gra­tion continue a été évoquée pour la toute première fois dans la des­crip­tion de la méthode agile de l’Extreme Pro­gram­ming de Kent Beck. Mais a priori, l’idée d’une in­té­gra­tion continue serait an­té­rieure. Elle in­ter­vient par exemple déjà dans la méthode Booch.

Qu’est-ce que la con­ti­nuous in­te­gra­tion ?

L’in­té­gra­tion continue nous fournit une bonne solution lorsque l’en­tre­prise travaille sur un vaste projet ou un client souhaite avoir un logiciel à la fois complet et complexe. Dif­fé­rentes équipes tra­vail­lent à la con­cep­tion de pans de l’ap­pli­ca­tion et les dé­ve­lop­peurs se chargent de pro­gram­mer les dif­fé­rentes fonc­tion­na­li­tés. Après un travail de plusieurs mois voire de plusieurs années, l’in­té­gra­lité du travail doit être regroupée et c’est alors que les problèmes sur­vien­nent. Dans un tel cas, la détection et la cor­rec­tion des erreurs, le re­grou­pe­ment de tous les fragments de code peut prendre plusieurs mois pour fi­na­le­ment se rap­pro­cher de la phase de test finale et du dé­ploie­ment.

Dans le cadre de la con­ti­nuous in­te­gra­tion, l’in­té­gra­tion du nouveau code est effectuée de façon bien plus précoce et pas uni­que­ment lorsque toutes les parties prenantes ont terminé leur sous-domaine. Au lieu de cela, les dé­ve­lop­peurs intègrent leur code terminé une ou plusieurs fois par jour dans la mainline, le code source qui est ac­ces­sible par tous les pro­gram­meurs. Étant donné qu’il s’agit toujours dans ce cas de sections de code re­la­ti­ve­ment courtes, l’in­té­gra­tion est elle aussi plutôt rapide. Seules quelques minutes sont né­ces­saires à un dé­ve­lop­peur pour mettre le résultat de son travail à dis­po­si­tion du reste de l’équipe. Si l’on découvre alors une erreur, elle peut être im­mé­dia­te­ment localisée et, dans le meilleur des cas, corrigée ra­pi­de­ment.

Dé­fi­ni­tion

La con­ti­nuous in­te­gra­tion (en français « in­té­gra­tion continue ») est une technique de dé­ve­lop­pe­ment de logiciel agile. Pour ce type d’in­té­gra­tion, les dé­ve­lop­peurs intègrent les fragments de code terminés ré­gu­liè­re­ment, parfois plusieurs fois par jour, dans l’ap­pli­ca­tion au lieu de les intégrer tous en même temps à la fin du projet.

Manière de procéder

En pratique, l’in­té­gra­tion continue se déroule gé­né­ra­le­ment de la façon suivante : un dé­ve­lop­peur a pour tâche de créer une fonc­tion­na­lité. Avant de s’atteler au travail de pro­gram­ma­tion, il té­lé­charge la version actuelle du code complet de l’ap­pli­ca­tion, qu’on appelle mainline. Il peut tra­vail­ler dans cette version qui se trouve à présent sur son or­di­na­teur personnel (également appelée working copy). Lorsqu’il a terminé sa tâche, il teste le programme, corrige les erreurs éven­tuelles et peut à présent publier la nouvelle version dans la mainline.

Le dé­ve­lop­peur n’est toutefois pas seul à tra­vail­ler sur le programme. Alors qu’il procédait à ses mo­di­fi­ca­tions, ses collègues ont très cer­tai­ne­ment effectué d’autres tâches et chaque dé­ve­lop­peur de l’équipe dispose ainsi d’une version dif­fé­rente sur son or­di­na­teur. Par ailleurs, des mo­di­fi­ca­tions ont pu être apportées à la version de la mainline depuis son té­lé­char­ge­ment et le pro­gram­meur doit donc tout d’abord les intégrer dans sa copie de travail (working copy). Si une erreur se produit, à lui de la corriger. Une fois ce travail réalisé, le pro­gram­meur peut alors insérer ses mo­di­fi­ca­tions dans la mainline. Il teste une nouvelle fois le programme. Lorsqu’aucune erreur ne se produit lors du test (une erreur pouvant par exemple survenir s’il n’a pas actualisé cor­rec­te­ment sa copie de travail), le processus est ef­fec­ti­ve­ment terminé et le dé­ve­lop­peur peut se consacrer à sa tâche suivante.

Com­por­te­ments

Plusieurs règles doivent être observées lorsque l’on travaille de cette façon : en procédant de la sorte, les pro­gram­meurs se basent gé­né­ra­le­ment sur les principes élaborés à l’époque par Martin Fowler (lui-même dé­ve­lop­peur de logiciel) pour réussir une in­té­gra­tion continue. Ces principes visent tout d’abord à garantir que toutes les parties prenantes se trouvent au même niveau et que personne n’entraîne de ca­tas­trophe en adoptant une approche dif­fé­rente.

Une seule et même source

Même si cela semble évident, il s’agit d’un des prin­ci­paux facteurs : tous les membres de l’équipe doivent utiliser la même source (le même dépôt ou re­po­si­tory) lorsqu’ils tra­vail­lent sur le code. Cela ne s’applique pas uni­que­ment au code source à pro­pre­ment parler. En effet, d’autres éléments, comme des bases de données, sont né­ces­saires pour garantir une ap­pli­ca­tion viable. Ces bases de données doivent également être re­grou­pées en un même endroit. C’est pourquoi Martin Fowler re­com­mande de mettre en place un dépôt, de telle sorte que même un dé­ve­lop­peur s’équipant d’un or­di­na­teur de travail en­tiè­re­ment neuf puisse tra­vail­ler et trouver l’ensemble des fichiers né­ces­saires de façon cen­tra­li­sée à un seul et même endroit.

Conseil

Pour que la gestion d’une telle source fonc­tionne ef­fi­ca­ce­ment, il est pertinent d’utiliser un système de gestion de versions. Dans le cas d’un nombre important de col­la­bo­ra­teurs, il est nettement plus simple de garder une vue d’ensemble avec un logiciel adapté.

Builds au­to­ma­ti­sés

Afin de concevoir un programme viable à partir du code source, les dé­ve­lop­peurs doivent le compiler, ac­tua­li­ser les bases de données et déplacer les fichiers au bon endroit. Ce processus peut être au­to­ma­tisé. Dans l’idéal, il faudrait pouvoir exécuter un processus de build à l’aide d’une seule commande.

Système avec test au­to­ma­tique

En intégrant des mé­ca­nismes de test dans le processus de build, l’équipe profite d’une plus grande au­to­ma­ti­sa­tion et ainsi d’une ac­cé­lé­ra­tion de l’in­té­gra­tion continue. Tout comme le processus de build à pro­pre­ment parler, les tests peuvent être exécutés avec un minimum d’effort (pour bien faire, on peut im­plé­men­ter tout un groupe de dif­fé­rents mé­ca­nismes de test).

Note

La méthode agile dite « Test Driven De­ve­lop­ment » (TDD) accorde une grande im­por­tance aux tests. D’après Martin Fowler, il n’est pas né­ces­saire de mettre en œuvre l’in­té­gra­lité du TDD pour utiliser l’in­té­gra­tion continue.

In­té­gra­tion quo­ti­dienne

L’in­té­gra­tion continue peut uni­que­ment fonc­tion­ner lorsque tous les membres de l’équipe con­tri­buent au système. Lorsqu’un collègue publie un code non définitif dans la mainline, les autres partent sur des bases erronées. Tous acceptent de tra­vail­ler à un système stable, mais si quelqu’un retient le code pendant une trop longue période (plus d’un jour), la recherche d’erreurs qui s’ensuit peut devenir un problème. Comme souvent, la com­mu­ni­ca­tion est un facteur essentiel dans l’in­té­gra­tion continue, mais lorsque les dé­ve­lop­peurs se tiennent ré­gu­liè­re­ment informés, les petites dif­fi­cul­tés peuvent être ra­pi­de­ment sur­mon­tées.

Mainline opé­ra­tion­nelle

Le code de programme que l’on trouve dans la mainline doit toujours être testé et opé­ra­tion­nel. C’est pourquoi chaque dé­ve­lop­peur peut intégrer son code uni­que­ment dans cette branche prin­ci­pale et non dans une branche se­con­daire per­son­nelle. Ce faisant, chaque dé­ve­lop­peur doit par ailleurs veiller à ce que sa con­tri­bu­tion per­son­nelle soit opé­ra­tion­nelle. Après l’in­té­gra­tion, il doit également tester le code et le build. Si une erreur se produit, il doit la corriger. Ceci permet de garantir un code toujours exempt d’erreurs.

Ré­pa­ra­tion immédiate

En cas d’in­té­gra­tion continue, il est capital que la mainline ne comporte pas de version erronée. Pour les dé­ve­lop­peurs, cela implique que les cor­rec­tions ne peuvent pas être reportées. D’après Martin Fowler, le fait que des builds ne fonc­tion­nent pas et que le code doive être re­tra­vaillé ne constitue pas un problème en soi, mais le système d’in­té­gra­tion continue exige que la cor­rec­tion soit effectuée im­mé­dia­te­ment. En effet, l’ensemble des dé­ve­lop­peurs doivent pouvoir compter sur un code fonc­tion­nel dans la Mainline. Si tel n’est pas le cas, toute l’équipe travaille dans des systèmes instables, ce qui déclenche une avalanche d’erreurs.

Une courte période d’in­té­gra­tion

L’in­té­gra­tion effective du code (y compris la phase de test) doit être effectuée aussi ra­pi­de­ment que possible. L’« extreme pro­gram­ming » (XP) prévoit 10 minutes seulement pour l’in­té­gra­tion. Étant donné que, dans certaines cir­cons­tances, un dé­ve­lop­peur est amené à intégrer le code plusieurs fois par jour, les délais de build en­traî­nent des pertes de temps con­si­dé­rables. Il est par con­sé­quent né­ces­saire de mettre en place des mé­ca­nismes ac­cé­lé­rant le processus. Afin d’atteindre une telle rapidité, il faut également accepter de ne pas effectuer di­rec­te­ment chaque test possible et ima­gi­nable. On choisit plutôt d’im­plé­men­ter un système en deux étapes : lors de la première phase, qui survient au cours du travail quotidien, les tests sont effectués de telle sorte que l’on puisse atteindre des délais de build courts. La seconde phase de test dure en revanche plusieurs heures et comprend également des vé­ri­fi­ca­tions plus ap­pro­fon­dies.

En­vi­ron­ne­ment de test copié

Il est en principe pertinent d’effectuer des tests dans un en­vi­ron­ne­ment dé­lo­ca­lisé et sécurisé. Il convient toutefois de veiller dans ce cadre à ce que les tests soient con­fi­gu­rés de la même façon que dans l’en­vi­ron­ne­ment de pro­duc­tion. Dans certains cas, cela peut s’avérer très coûteux, car la machine doit être réglée pré­ci­sé­ment de la même façon. Toutefois, grâce la vir­tua­li­sa­tion d’or­di­na­teurs complets, ce facteur de coût est toujours moins important.

Un accès simple

Toutes les parties prenantes doivent pouvoir accéder sim­ple­ment à la dernière version et exécuter le programme. Y parvenir est re­la­ti­ve­ment simple : étant donné que l’in­té­gra­tion continue impose dans tous les cas le re­grou­pe­ment de tous les fichiers dans un même dépôt, cet em­pla­ce­ment doit être connu de tous. Il y a plusieurs bonnes raisons à cela : les testeurs peuvent ainsi commencer sans attendre les tests sup­plé­men­taires lors du processus de pro­gram­ma­tion en cours, les parties prenantes peuvent utiliser les fichiers exé­cu­tables à des fins de dé­mons­tra­tion et les ges­tion­naires de la qualité peuvent vérifier les chiffres.

Une com­mu­ni­ca­tion claire et com­pré­hen­sible

Il est essentiel que toutes les parties prenantes aient accès au texte et au fichier exé­cu­table et sachent clai­re­ment qui doit procéder à quelles mo­di­fi­ca­tions. La com­mu­ni­ca­tion inclut également le fait que les dé­ve­lop­peurs s’entendent entre eux lorsqu’ils sont dans un processus de build. Pour cela, certaines équipes utilisent des af­fi­chages séparés ou des re­pré­sen­ta­tions visuelles qui indiquent qu’une in­té­gra­tion est en cours.

Une ré­par­ti­tion au­to­ma­ti­sée

Il est par ailleurs né­ces­saire d’au­to­ma­ti­ser la ré­par­ti­tion lo­gi­cielle. Les fichiers doivent être trans­po­sés d’un en­vi­ron­ne­ment à un autre, ce qui peut s’avérer chro­no­phage. Ici, il est donc pertinent d’utiliser des scripts. Ces scripts per­met­tent d’au­to­ma­ti­ser et d’accélérer le processus.

Avantages et in­con­vé­nients d’une in­té­gra­tion continue

Lors du travail quotidien, on constate souvent que l’in­té­gra­tion continue ne présente pas que des avantages en dépit de ses qualités. Si elle permet ef­fec­ti­ve­ment de faire l’économie d’une phase d’in­té­gra­tion longue et fas­ti­dieuse en fin de projet et de régler les problèmes de façon précoce, pour les équipes qui in­ter­vien­nent, le passage à l’in­té­gra­tion continue peut s’avérer très compliqué. Dans un tel cas, ce processus peut même demander plus de temps qu’il ne permet d’en éco­no­mi­ser.

Avantages In­con­vé­nients
Pos­si­bi­lité de recherche précoce des erreurs Con­ver­sion de processus habituels
Feedback permanent Nécessite des serveurs et des en­vi­ron­ne­ments sup­plé­men­taires
Pas de surcharge con­trai­re­ment à une seule grande in­té­gra­tion finale Nécessité de mettre au point des processus de test adaptés
En­re­gis­tre­ment précis des mo­di­fi­ca­tions Si plusieurs dé­ve­lop­peurs sou­hai­tent intégrer leur code ap­proxi­ma­ti­ve­ment au même moment, des délais d’attente peuvent survenir
Dis­po­ni­bi­lité continue d’une version actuelle opé­ra­tion­nelle  
Nécessité d’un travail pro­gres­sif  

Pré­sen­ta­tion des outils d’in­té­gra­tion continue utiles

En principe, il est possible de gérer une in­té­gra­tion continue sans outil créé spé­cia­le­ment à cet effet, car toutes les étapes de travail peuvent être ef­fec­tuées ma­nuel­le­ment. Cela demande toutefois une très grande dis­ci­pline et un effort encore plus con­sé­quent. Il est possible de se faciliter la tâche avec des outils utiles. Ces derniers mettent gé­né­ra­le­ment un serveur à dis­po­si­tion et aident à la cons­truc­tion et au contrôle des versions.

  • Jenkins : le très populaire Jenkins est programmé sous Java et est un fork de Hudson dont le dé­ve­lop­pe­ment a été arrêté depuis. Ce logiciel open source utilise dif­fé­rents outils de build et des systèmes de gestion de versions.
  • Travis CI : cet outil d’in­té­gra­tion continue est par­ti­cu­liè­re­ment apprécié car il fonc­tionne sans dif­fi­culté avec GitHub. Le dépôt en ligne informe Travis des mo­di­fi­ca­tions survenues dans le code. Le logiciel est dis­po­nible en version gratuite pour les projets open source et en version payante pour tous les autres projets.
  • Bamboo : avec le serveur Bamboo, les dé­ve­lop­peurs peuvent procéder à l’in­té­gra­tion, au dé­ploie­ment et à la gestion des versions. Le fabricant Atlassian propose ce logiciel en tant qu’interface Web basée sur Java. Bamboo assiste les dé­ve­lop­peurs avec des au­to­ma­ti­sa­tions et fonc­tionne avec dif­fé­rents outils de build. Pour les projets open source, cette offre nor­ma­le­ment payante est également dis­po­nible gra­tui­te­ment.
  • GitLab CI : GitLab propose un programme propre pour l’in­té­gra­tion continue qui fonc­tionne avec ce célèbre système de gestion des versions. Le pipeline peut être per­son­na­lisé et adapté à chaque projet. Par ailleurs, GitLab supporte également CI Docker.
  • CircleCI : ce programme d’in­té­gra­tion continue est dis­po­nible en deux versions. Il est possible d’opter pour une version di­rec­te­ment sur le Cloud du four­nis­seur ou de créer un serveur local dédié pour l’uti­li­sa­tion.
  • Crui­se­Con­trol : ini­tia­le­ment développé par Thought­Works (une société bâtie autour de Martin Fowler), Crui­se­Con­trol est entre-temps devenu un projet in­dé­pen­dant. Ce logiciel libre est basé sur Java et peut être utilisé sur dif­fé­rentes pla­te­formes. Crui­se­Con­trol offre notamment aux dé­ve­lop­peurs un tableau de bord, un site Internet propre, sur lequel ils peuvent iden­ti­fier l’état du build.
  • Codeship : Codeship entend fournir aux dé­ve­lop­peurs une pos­si­bi­lité d’in­té­gra­tion continue d’une extrême sim­pli­cité. Des au­to­ma­tismes peuvent être fa­ci­le­ment créés sur la base de la tech­no­lo­gie de con­te­neurs. Pour cette tâche, l’en­tre­prise propose deux versions dif­fé­rentes : la version basique et la version pro.
  • TeamCity : le logiciel com­mer­cial TeamCity accorde une grande im­por­tance à l’in­te­ro­pé­ra­bi­lité avec d’autres outils. De nombreux pro­grammes sont déjà supportés par la version standard, mais la gamme peut également être étendue avec des plugins. On trouve par ailleurs une autre par­ti­cu­la­rité dans l’approche « Pre-Tested Commit ». TeamCity vérifie au­to­ma­ti­que­ment le code réécrit avant l’in­té­gra­tion dans la mainline et informe le dé­ve­lop­peur en cas d’erreurs.
Note

Dans notre article de fond, vous en ap­pren­drez davantage sur les avantages et les in­con­vé­nients des dif­fé­rents outils d’in­té­gra­tion continue.

Aller au menu principal