L’intégration continue (CI) est une pratique de développement logiciel dans laquelle les développeurs intègrent régulièrement du nouveau code et des modifications dans un référentiel de code central tout au long du cycle de développement. Elle constitue un élément clé des méthodologies DevOps et agiles.
L’intégration continue est la première partie du pipeline CI/CD, un workflow DevOps automatisé qui rationalise le processus de livraison des logiciels. Grâce à l’intégration continue, les équipes DevOps peuvent améliorer en permanence leurs applications logicielles, recevoir des commentaires constructifs, détecter et corriger les erreurs avant qu’elles ne nuisent aux performances des logiciels, et fournir des logiciels de meilleure qualité selon des calendriers de livraison plus prévisibles.
Lorsqu’un développeur valide des modifications de code dans une branche principale ou partagée d’un système de contrôle de version, cette action déclenche un outil CI qui effectue une « compilation » de la base de code mise à jour. Le système CI récupère le nouveau code, le compile avec le code existant et le regroupe avec toutes les dépendances, telles que les fichiers de configuration, les bibliothèques ou toute autre ressource. Cela constitue la « compilation ».
Des tests automatisés sont effectués pour la valider avant qu’un « artefact de compilation » (le fichier résultant qui est transmis pour des tests supplémentaires ou vers un environnement de production) ne soit généré. L’étape suivante du pipeline est appelée livraison continue.
La CI a été conçue comme une solution aux problèmes du développement logiciel traditionnel, en particulier ses processus d’intégration et de déploiement. Dans ces paradigmes classiques, chaque développeur devait intégrer manuellement son code dans les nouvelles versions d’une application ou d’un service. Cette intégration manuelle était chronophage et source d’erreurs, surtout pour les grandes équipes.
Les différentes parties du code ne fonctionnaient pas toujours bien ensemble, et les développeurs intégraient leurs changements selon des calendriers variés (parfois à la dernière minute), ce qui retardait souvent la détection des problèmes d’intégration. Quand des problèmes survenaient, ces retards compliquaient l’identification des changements à leur origine et rendaient le débogage plus ardu.
De plus, les tests logiciels étaient rares : les équipes appliquaient d’un bloc de grosses mises à jour par lots, ce qui laissait passer des bugs, qui s’accumulaient dans la base de code. Résultat : débogage plus difficile pour les équipes de développement, taux d’échec plus élevés, sorties de code ralenties, pertes de revenus pour les entreprises en raison de ces inefficacités et davantage d’erreurs et d’incidents côté utilisateur.
Composante fondamentale des pratiques DevOps modernes, des pipelines d’intégration continue/déploiement continu (CI/CD) et des architectures de microservices, l’intégration continue contribue à rationaliser le processus de compilation en fournissant un retour rapide sur les performances d’intégration.
Avec un système CI, le nouveau code est ajouté à un référentiel central (généralement plusieurs fois par jour), où il est compilé et testé. Si le système détecte une erreur, il envoie des notifications, corrige le code et confirme que le code mis à jour est correct avant de le fusionner complètement avec la base de code du logiciel.
Newsletter sectorielle
Restez au fait des tendances les plus étonnantes du secteur dans le domaine de l’IA, de l’automatisation, des données et bien d’autres avec la newsletter Think. Consultez la déclaration de confidentialité d’IBM.
Lire la Déclaration de confidentialité d’IBM.
Vous recevrez votre abonnement en anglais. Vous trouverez un lien de désabonnement dans chaque newsletter. Vous pouvez gérer vos abonnements ou vous désabonner ici. Consultez la Déclaration de confidentialité d’IBM pour plus d’informations.
Bien que la configuration exacte d’un système CI puisse varier d’une équipe ou d’une entreprise à l’autre, chaque système repose sur des composants et processus spécifiques pour optimiser les tâches d’intégration de code.
La CI commence par un référentiel central partagé où tous les développeurs déposent leur code. Ce type de référentiels est au cœur des pratiques CI, et ils sont souvent gérés par des systèmes de contrôle de version (VCS), comme Git ou Bitbucket. À chaque modification soumise, le référentiel garde une trace complète de l’historique des changements, facilitant ainsi la collaboration au sein des équipes de développement.
Ces référentiels utilisent également des techniques de branching, qui créent des lignes de développement séparées pour isoler les modifications en cours dans la base de code principale (branche principale) et ainsi faciliter le développement en parallèle. Le branching (création de branches) permet aux développeurs de créer des feature branches (branches dédiées à des fonctionnalités spécifiques) ainsi que des branches temporaires, afin d’isoler leur travail avant de le réintégrer dans la branche principale du code.
Gitflow, par exemple, est un modèle de branchement basé sur Git qui attribue des rôles (tels que « main » ou branche principale, « feature » ou branche de fonctionnalité, « develop » ou branche de développement, et « release » ou branche de version) à différentes branches afin de régir leur interaction. Les branches Gitflow exigent des développeurs qu’ils créent des branches de fonctionnalités et attendent que la fonctionnalité soit terminée pour fusionner les modifications de code dans la branche principale.
Les serveurs CI sont des outils qui centralisent et gèrent toutes les opérations CI. Ils servent de centre d’automatisation du processus CI. Les serveurs CI surveillent les référentiels pour détecter les modifications de code et lancent et alimentent des pipelines CI prédéfinis lorsque des modifications sont détectées. Les serveurs CI exécutent des compilations, des tests et des versions logicielles automatisés, orchestrent les protocoles de contrôle de version, gèrent les rapports d’état et prennent en charge des modules d’extension qui peuvent améliorer les fonctionnalités du système.
De nombreux serveurs CI proposent des interfaces utilisateur permettant aux équipes de modéliser et visualiser leurs workflows et de construire leurs pipelines d’intégration continue/livraison continue (CI/CD).
Les systèmes CI encouragent les développeurs à soumettre leurs modifications plusieurs fois par jour, en privilégiant des changements ciblés et limités à des tâches ou fonctionnalités spécifiques. Avec les outils CI, les équipes peuvent initier des révisions de code et discuter des problèmes avant d’intégrer le nouveau code, afin de détecter les erreurs dès le début du processus de développement.
Un système CI basé sur Git peut, par exemple, lancer des demandes d’extraction pour récupérer les modifications de code d’une branche locale (stockée localement sur l’ordinateur d’un seul développeur) et les intégrer dans la branche distante actuelle (stockée à distance et partagée par toute l’équipe de développement). Les demandes de fusion permettent aux développeurs d’intégrer les modifications proposées à partir d’une branche locale dans une autre branche locale afin que l’équipe puisse les examiner, en discuter et les approuver avant de les fusionner avec la branche distante.
Les serveurs et outils CI (y compris des solutions open source populaires comme Jenkins, CircleCI, GitHub, AWS CodePipeline et GitLab CI) surveillent en permanence le référentiel central pour détecter les modifications de code. Dès qu’une modification est repérée, les serveurs CI déclenchent automatiquement le processus de build, exécutent des workflows et scripts prédéfinis, compilant et empaquetant le code en vue des tests et, à terme, du déploiement.
Les outils CI exécutent une série de tests pour valider le code avant qu’il ne soit fusionné avec la base de code principale. Les tests unitaires vérifient les fonctions ou composants individuels en fournissant un retour immédiat sur le comportement du code. Les tests d'intégration, quant à eux, vérifient que les différents composants logiciels fonctionnent bien ensemble, identifiant les problèmes que les tests unitaires pourraient avoir manqués.
Dans certains workflows CI, les tests de bout en bout valident le logiciel en simulant les interactions des utilisateurs afin de vérifier que le logiciel se comporte correctement du point de vue de l’utilisateur. Les équipes peuvent également exécuter des tests de qualité du code et des analyses statiques pour évaluer la réactivité et la stabilité de l’application sous charge et pour identifier les violations des normes de codage et les vulnérabilités de sécurité.
Les serveurs CI avertissent immédiatement les développeurs en cas d’échec d’une compilation ou d’un test. En cas d’échec, les développeurs peuvent privilégier la réparation du code afin de garantir que la branche principale reste déployable.
Si la compilation logicielle réussit, les serveurs produisent des artefacts (fichiers créés durant le processus de build, comme du code compilé, des images Docker ou des bibliothèques), qui sont versionnés et stockés dans des dépôts pour de futurs tests et déploiements. Quel que soit le résultat, les meilleurs systèmes CI enregistrent les tentatives d’intégration, les taux de réussite et d’autres indicateurs, afin que les membres de l’équipe aient toujours accès à une documentation complète des versions.
Les tests jouent un rôle crucial dans les processus d’intégration continue. Au minimum, ils représentent environ un tiers des activités CI, mais cela dépend aussi du nombre d’étapes de tests effectuées par les équipes. Souvent, les activités de test constituent la majeure partie du workload des outils CI.
Les tests continus en environnement CI commencent lorsqu’un développeur dépose du nouveau code dans la base de code. Cette action déclenche un build et un processus de test automatisé. Dans de nombreux cas, des tests supplémentaires sont effectués une fois l’artefact généré (avant que le code ne parte en production). Il est également important que les développeurs exécutent tous les tests, ainsi que des sous-ensembles de tests, dans leur environnement local, afin de s’assurer que le code soumis au contrôle de version a passé tous les tests avec succès.
Ces tests polyvalents de diverses fonctions, cas d’utilisation et intégrations sont collectivement appelés « suite de tests ». Cette approche maximise la couverture des tests, empêche la régression du code et jette les bases d’une livraison continue réussie.
Le développement piloté par les tests (TDD) est une autre approche du développement logiciel dans laquelle les développeurs « travaillent à rebours », en écrivant le test avant d’écrire le moindre code. Dans cette approche, les développeurs écrivent un cas de test au niveau de l’unité qui échoue, avant d’écrire le minimum de code nécessaire pour qu’il réussisse. Une fois cela fait, le code de test et le code de production peuvent être refactorisés et améliorés.
Cette approche permet aux développeurs de rester concentrés sur des exigences bien définies et d’éviter le code superflu. Elle met aussi l’accent sur le feedback continu, et peut constituer une technique efficace pour accélérer les cycles de développement.
Les pipelines DevOps accélèrent la livraison de logiciels de haute qualité en automatisant et en combinant les efforts des équipes de développement et des opérations informatiques, qui travaillaient traditionnellement en silos.
Les processus et cultures DevOps efficaces vont au-delà du développement et des opérations et incluent l’ingénierie des plateformes et des infrastructures, la sécurité, la conformité, la gouvernance, la gestion des risques, mais aussi les utilisateurs finaux et les clients. En d’autres termes, une bonne approche DevOps implique toutes les parties prenantes dans le cycle de vie du développement logiciel.
Selon les principes du DevOps, l’intégration continue se place au début du processus de développement logiciel et du pipeline CI/CD. La CI permet aux développeurs de vérifier fréquemment leur code pour empêcher les copies locales de trop s’éloigner de la branche principale du code. Cette pratique permet aux équipes d’éviter les conflits de fusion susceptibles de « casser » le build lors des phases de livraison et de déploiement.
La CI permet aussi de soumettre de petites mises à jour fréquentes qui favorisent des boucles de rétroaction rapides et régulières, ainsi qu’une amélioration continue fondée sur la hiérarchisation des besoins des clients : des principes fondamentaux de la philosophie DevOps.
L’intégration continue est la première étape du pipeline CI/CD, suivie des processus de livraison continue et de déploiement continu. L’intégration continue désigne les fusions fréquentes de code, suivies des builds et des tests unitaires.
La livraison continue (CD) prend le relais de l’intégration continue, en automatisant la livraison des modifications validées de la base de code (y compris les mises à jour, les corrections de bogues et même les nouvelles fonctionnalités) dans des environnements ou des référentiels de code sélectionnés. Les équipes DevOps reçoivent des notifications concernant la dernière compilation et peuvent transférer manuellement les mises à jour dans un environnement de production en direct. L’objectif de la phase de pipeline de livraison continue est de déployer le nouveau code avec un minimum d’efforts, tout en permettant un certain niveau de supervision humaine avant la mise en production du code.
Le déploiement continu publie automatiquement les modifications de code pour les utilisateurs finaux après la réussite à une série de tests prédéfinis, tels que les tests d’intégration qui testent le code dans un environnement miroir afin de garantir l’intégrité du code. La distribution continue et le déploiement continu impliquent tous deux l’automatisation plus en aval du pipeline par rapport à l’intégration continue, et ils sont souvent utilisés de manière interchangeable.
La différence entre la livraison continue et le déploiement continu réside dans le niveau d’automatisation utilisé dans les versions de logiciels ou d’applications. Dans la livraison continue, le code est automatiquement transféré vers des environnements de type production pour des tests supplémentaires et une assurance qualité, tels que l’évaluation des risques et l’identification des vulnérabilités du code source. Une intervention humaine est nécessaire pour passer en production après la réussite des tests.
Dans le déploiement continu, l’automatisation va plus loin. Une fois que le code a passé les tests, le déploiement en production se fait automatiquement ; aucune approbation humaine n’est nécessaire.1
Le développement agile est une approche itérative de l’ingénierie logicielle qui privilégie la flexibilité, la collaboration, l’amélioration continue et l’adaptation rapide au changement. Cette pratique organise le développement en petits blocs de travail, ou « sprints », pour faciliter la collaboration entre développeurs et parties prenantes, et accélérer la livraison des logiciels.
De manière similaire, la CI repose sur des mises à jour de code fréquentes et incrémentales ainsi que sur une validation continue. C’est une approche itérative qui permet aux développeurs d’accélérer la mise à niveau et le déploiement des solutions logicielles, ainsi que de livrer des produits de haute qualité plus rapidement aux utilisateurs. À ce titre, l’intégration continue est intrinsèquement une pratique agile.
L’intégration continue aide les équipes de développement à itérer plus rapidement et à livrer de meilleurs logiciels aux utilisateurs, mais certaines pratiques permettent d’optimiser encore le processus. Voici les pratiques de CI couramment mises en œuvre :
Une base de code consolidée et centralisée peut simplifier la distribution et la visibilité. De nombreuses organisations utilisent la gestion du contrôle du code source pour maintenir un référentiel unique qui suit et contrôle tous les fichiers associés à la compilation d'un produit.
Les organisations peuvent instaurer une culture de cohérence en exigeant des développeurs qu’ils valident leurs modifications dans le flux de développement principal au moins une fois par jour afin de vérifier que leur copie de travail est conforme.
L’optimisation des scripts de compilation, la parallélisation des tâches et l’utilisation de mécanismes de mise en cache peuvent réduire les temps de compilation. Les équipes peuvent également configurer les pipelines CI afin que les nouvelles intégrations soient validées très tôt dans le processus d’itération. Cette approche proactive permet aux développeurs de résoudre les problèmes rapidement et de passer moins de temps à déboguer.
Créer un environnement de test aussi proche que possible de l’environnement de production peut contribuer à garantir que les résultats des tests sont représentatifs du comportement réel du logiciel.
La mise en œuvre d'indicateurs de fonctionnalités pour contrôler la publication des nouvelles fonctionnalités permet aux systèmes de CI de fusionner des fonctionnalités incomplètes ou expérimentales dans la branche principale sans affecter la production.
La révision et la mise à jour fréquentes du pipeline CI pour intégrer de nouveaux outils et de nouvelles technologies et bonnes pratiques permet aux équipes DevOps de renforcer le pipeline et d’adapter les pratiques de développement à l’évolution des besoins du projet.
Avec le TDD, les tests sont écrits avant l’implémentation de tout code de fonctionnalité. L’équipe de développement et l’équipe produit collaborent pour définir les spécifications du produit, les exigences sont transformées checklist d’assertions de code et les développeurs rédigent du code répondant au test. Cette approche permet aux équipes d’intégrer un code de haute qualité et fiable dans les pipelines CI de manière proactive.
Les pratiques d’intégration continue, et les cadres DevOps plus largement, aident les entreprises à rationaliser la collaboration et l’intégration du code, et à maintenir des pipelines de livraison continue. De telles pratiques améliorent la qualité logicielle et accélèrent les cycles de mise en production. Les outils de CI modernes intègrent désormais un éventail de technologies émergentes qui renforcent ces pratiques et en accroissent leur valeur.
Par exemple, l’utilisation de l’intelligence artificielle (IA) et du machine learning (ML) dans les processus d’intégration continue est en passe de devenir une pratique de développement standard. Les outils basés sur l’IA permettent aux développeurs de créer des systèmes auto-réparateurs capables d’identifier et de corriger automatiquement et de manière autonome du code problématique avant qu’il n’affecte le flux principal de développement. Les systèmes CI pilotés par ML peuvent également générer automatiquement des scénarios de test personnalisés en fonction des soumissions et des modifications de code, afin que les développeurs consacrent moins de temps à la création manuelle de ces tests.
Face à la sophistication croissante des cybermenaces,2 les développeurs intègrent de plus en plus les pratiques de sécurité directement dans le processus de développement logiciel. Ces stratégies de sécurité « shift-left » introduisent des contrôles de sécurité dès les premières phases du développement (y compris les processus CI) afin de garantir que les vulnérabilités soient détectées pendant le codage plutôt qu’après le déploiement.
Aujourd’hui, Kubernetes et l’écosystème plus large des technologies liées aux conteneurs constituent les fondements des environnements informatiques modernes. Le DevSecOps intègre la sécurité à chaque phase du DevOps afin de relever les défis en la matière qui accompagnent ces écosystèmes dynamiques.
Les conteneurs sont des unités logicielles exécutables qui regroupent le code d’une application avec ses bibliothèques et dépendances, afin qu’il puisse s’exécuter dans n’importe quel environnement informatique. Kubernetes, aussi connu sous le nom de k8s ou kube, est une plateforme d’orchestration de conteneurs open source permettant de planifier et d’automatiser le déploiement, la gestion et la mise à l’échelle d’applications conteneurisées.
Traditionnellement, les équipes DevOps s’appuyaient sur une équipe de sécurité distincte pour identifier les vulnérabilités, puis utilisaient ses retours pour appliquer des correctifs lors du cycle de mise à jour suivant. Désormais, les développeurs doivent sécuriser les conteneurs et clusters Kubernetes eux-mêmes, et appliquer les principes du Zero Trust dans leurs applications logicielles et dans tout le processus de développement : un nouveau paradigme opérationnel.3 L’adoption des pratiques DevSecOps implique que le codage et le développement logiciel ne concernent plus uniquement la création de fonctionnalités, mais aussi l’anticipation des risques.
L’informatique sans serveur et les architectures cloud natives sont également une priorité pour les équipes DevOps d’aujourd’hui.
L’approche sans serveur (ou « serverless ») est un modèle de développement et d’exécution d’applications qui permet aux développeurs de générer et d’exécuter du code sans mettre en place ni gérer de serveurs ou d’infrastructure back-end. Les serveurs existent bel et bien dans une architecture sans serveur, mais ils sont entièrement gérés par un fournisseur de services cloud (CSP). Dans les pipelines CI, les plateformes sans serveur libèrent les développeurs des contraintes de l’infrastructure back-end, afin qu’ils se concentrent sur le code front-end et la logique métier.
Avec la prolifération de l’informatique sans serveur et des applications d’IA, les architectures orientées événements (EDA) jouent un rôle central en aidant les équipes à faire face à la complexité croissante du cloud computing. Les EDA prennent en charge la communication en temps réel entre les systèmes front-end et back-end faiblement couplés, permettant aux systèmes de fonctionner indépendamment et de traiter les événements (tout changement ou action qui se produit au sein d’un système) de manière asynchrone.
Dans les pipelines CI, les développeurs peuvent mettre à l’échelle des composants individuels d’une application sans affecter l’ensemble, ce qui rend les bases de code et les processus d’intégration plus agiles, réactifs et évolutifs.
La mise en place d’un pipeline CI robuste nécessite une planification minutieuse, notamment le choix des bons outils, la définition des workflows de compilation et de test, ainsi que la configuration de l’infrastructure. Ces pipelines doivent être entretenus régulièrement pour suivre les évolutions du code, des dépendances (comme les API) et de l’infrastructure.
Cependant, l’implémentation de la CI peut offrir de nombreux avantages, parmi lesquels :
Les processus de CI permettent de traiter les erreurs tôt dans le cycle, parfois en quelques minutes après la soumission du code.
Tous les membres de l’équipe peuvent modifier le code, fusionner les changements, identifier les incompatibilités et résoudre les erreurs d’intégration, ce qui favorise le partage des connaissances et améliore la qualité du code grâce aux retours des pairs.
Comme le code est intégré en continu, les équipes passent moins de temps à intégrer et à tester de grandes quantités de code. De plus, la boucle de rétroaction rapide offerte par les outils de CI permet aux développeurs d'itérer plus rapidement et de livrer des mises à jour logicielles ainsi que de nouveaux produits aux utilisateurs finaux.
Des commits fréquents de code se traduisent par des modifications plus petites et plus incrémentielles, qui sont plus faciles à comprendre, à réviser et à tester. Cela réduit les risques d'introduire des problèmes majeurs dans la base de code pendant le développement.
Automatisez la fourniture de logiciels pour toutes les applications sur site, dans le cloud ou sur mainframe.
Utilisez les logiciels et outils DevOps pour créer, déployer et gérer des applications cloud natives sur de nombreux appareils et environnements.
Déverrouillez de nouvelles fonctionnalités et stimulez l’agilité de votre entreprise grâce aux services de conseil d’IBM Cloud. Découvrez comment co-créer des solutions, accélérer la transformation numérique et optimiser les performances grâce à des stratégies de cloud hybride et à des partenariats d’experts.