84 votes

Gestion des branches multiples dans l'intégration continue

J'ai été confronté au problème de la mise à l'échelle du CI dans mon entreprise et, en même temps, j'ai essayé de déterminer l'approche à adopter en ce qui concerne le CI et les branches multiples. Il y a une question similaire sur stackoverflow, Branches de fonctionnalités multiples et intégration continue . J'en ai lancé une nouvelle parce que j'aimerais avoir plus de discussions et fournir une analyse de la question.

Jusqu'à présent, j'ai constaté qu'il y a deux approches principales que je peux adopter (ou peut-être d'autres ???).

Il semble donc que si je veux fournir aux développeurs un CI pour leurs propres branches personnalisées, j'ai besoin d'un outil spécial pour Jenkins (API ou shellscripts ou autre ?) et de gérer la mise à l'échelle. Ou je peux leur dire de fusionner plus souvent vers DEV et de vivre sans CI sur les branches personnalisées. Laquelle prendriez-vous ou y a-t-il d'autres options ?

69voto

Tom Howard Points 3301

Lorsque vous parlez de la mise à l'échelle de CI, vous parlez en fait de la mise à l'échelle de l'utilisation de votre serveur CI pour gérer toutes vos branches de fonctionnalités en même temps que votre ligne principale. Au départ, cela semble être une bonne approche car les développeurs d'une branche bénéficient de tous les avantages des tests automatisés inclus dans les tâches CI. Cependant, vous rencontrez des problèmes pour gérer les tâches du serveur CI (comme vous l'avez découvert) et, plus important encore, vous ne faites pas vraiment du CI. Oui, vous utilisez un serveur CI, mais vous n'intégrez pas continuellement le code de tous vos développeurs.

L'exécution d'un véritable CI signifie que tous vos développeurs s'engagent régulièrement dans la ligne principale. Facile à dire, mais le plus difficile est de le faire sans casser votre application. Je vous recommande vivement de consulter Livraison continue notamment le Faire en sorte que votre application puisse être libérée section dans Chapitre 13 : Gérer les composants et les dépendances . Les points principaux sont :

  • Cachez les nouvelles fonctionnalités jusqu'à ce qu'elles soient terminées. Toggles de fonctions ).
  • Effectuez toutes les modifications de manière incrémentielle, sous la forme d'une série de petites modifications, chacune d'entre elles étant publiable.
  • Utilisez la branche par abstraction pour apporter des modifications à grande échelle au codebase.
  • Utilisez des composants pour découpler les parties de votre application qui évoluent à des rythmes différents.

Ils sont assez explicites, à l'exception de la branche par abstraction. C'est juste un terme fantaisiste pour :

  1. Créez une abstraction sur la partie du système que vous devez modifier.
  2. Refactoriser le reste du système pour utiliser la couche d'abstraction.
  3. Créer une nouvelle implémentation, qui ne fait pas partie du chemin de code de production jusqu'à ce qu'elle soit terminée.
  4. Mettez à jour votre couche d'abstraction pour déléguer à votre nouvelle implémentation.
  5. Supprimez l'ancienne mise en œuvre.
  6. Supprimez la couche d'abstraction si elle n'est plus appropriée.

Le paragraphe suivant, tiré du Branches, flux et intégration continue section dans Chapitre 14 : Contrôle de version avancé résume les impacts.

L'approche incrémentale exige certainement plus de discipline et de soin - et même plus de créativité - que la création d'une branche et le plongeon à corps perdu dans la réarchitecture et le développement de nouvelles fonctionnalités. Mais elle réduit considérablement le risque que vos modifications cassent l'application, et vous fera gagner, à vous et à votre équipe, beaucoup de temps pour fusionner, réparer les pannes et mettre votre application dans un état déployable.

Il faut un sacré changement d'état d'esprit pour abandonner les branches caractéristiques et vous rencontrerez toujours de la résistance. D'après mon expérience, cette résistance est basée sur le fait que les développeurs ne se sentent pas en sécurité lorsqu'ils commettent du code sur la ligne principale, ce qui est une préoccupation raisonnable. Cela découle généralement d'un manque de connaissances, de confiance ou d'expérience dans les techniques énumérées ci-dessus et, éventuellement, d'un manque de confiance dans vos tests automatisés. Le premier problème peut être résolu par la formation et le soutien des développeurs. Le second est un problème beaucoup plus difficile à gérer, mais la ramification n'apporte aucune sécurité supplémentaire réelle, elle ne fait que reporter le problème jusqu'à ce que les développeurs se sentent suffisamment en confiance avec leur code.

4voto

Bernard Points 5492

Je mettrais en place des travaux séparés pour chaque branche. Je l'ai déjà fait et ce n'est pas difficile à gérer et à mettre en place si vous avez configuré Hudson/Jenkins correctement. Un moyen rapide de créer plusieurs travaux est de copier à partir d'un travail existant qui a des exigences similaires et de les modifier si nécessaire. Je ne sais pas si vous voulez permettre à chaque développeur de configurer ses propres tâches pour ses propres branches, mais ce n'est pas beaucoup de travail à gérer pour une seule personne (c'est-à-dire un gestionnaire de construction). Une fois que les branches personnalisées ont été fusionnées en branches stables, les travaux correspondants peuvent être supprimés lorsqu'ils ne sont plus nécessaires.

Si vous vous inquiétez de la charge du serveur de CI, vous pouvez configurer des instances séparées du CI ou même des esclaves séparés pour aider à équilibrer la charge sur plusieurs serveurs. Assurez-vous que le serveur sur lequel vous exécutez Hudson/Jenkins est adéquat. J'ai utilisé Apache Tomcat et j'ai simplement dû m'assurer qu'il avait suffisamment de mémoire et de puissance de traitement pour traiter la file d'attente de construction.

Il est important de savoir clairement ce que vous voulez réaliser à l'aide de CI, puis de trouver un moyen de le mettre en œuvre sans trop d'efforts manuels ou de duplications. Il n'y a rien de mal à utiliser d'autres outils ou scripts externes qui sont exécutés par votre serveur CI et qui contribuent à simplifier votre processus global de gestion des builds.

3voto

Anton Safonov Points 31

Je choisirais les branches dev+stable. Et si vous voulez toujours des branches personnalisées et que vous avez peur de la charge, alors pourquoi ne pas déplacer ces branches personnalisées vers le cloud et laisser les développeurs les gérer eux-mêmes, par ex. http://cloudbees.com/dev.cb C'est la société où Kohsuke est maintenant. Il y a aussi un Eclipse Tooling, donc si vous êtes sur Eclipse, vous l'aurez étroitement intégré directement dans dev env.

1voto

prosailor Points 31

En fait, ce qui est vraiment problématique, c'est l'isolation de la construction avec les branches de fonctionnalités. Dans notre entreprise, nous avons un ensemble de projets maven séparés qui font tous partie d'une distribution plus large. Ces projets sont maintenus par différentes équipes, mais pour chaque distribution, tous les projets doivent être publiés. Une branche de fonctionnalité peut maintenant se chevaucher d'un projet à l'autre et c'est là que l'isolation de la construction devient pénible. Il y a plusieurs solutions que nous avons essayées : * créer des dépôts snapshot séparés dans nexus pour chaque branche de fonctionnalité * partager des dépôts locaux sur des esclaves dédiés * utiliser le plugin repository-server avec des dépôts en amont * construire tout dans un seul travail avec un dépôt privé

En fait, la dernière solution est la plus prometteuse. Toutes les autres solutions présentent des lacunes d'une manière ou d'une autre. Avec le plugin job-dsl, il est facile de mettre en place une nouvelle branche de fonctionnalité. Il suffit de copier et coller le groovy script, d'adapter les branches et de laisser le seed job créer les nouveaux jobs. Assurez-vous que le job d'amorçage supprime les jobs non gérés. Ensuite, vous pouvez facilement évoluer avec les branches de fonctionnalités sur différents projets maven.

Mais comme Tom l'a dit bien plus haut, il serait plus agréable de surmonter la nécessité des branches de fonctionnalités et d'apprendre aux développeurs à intégrer proprement, mais c'est un processus plus long et le résultat n'est pas clair avec de nombreuses parties de systèmes hérités que vous ne toucherez plus.

mes deux cents

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X