Je fais partie d'un groupe de développement avec 5 équipes, un total d'environ 40 développeurs. Nous suivons la méthodologie Scrum, avec des sprints de 3 semaines. Nous avons une configuration d'intégration continue (Jenkins), avec un pipeline de construction prenant plusieurs heures (en raison de tests automatisés approfondis). Fondamentalement, le processus de développement fonctionne bien.
Cependant, nous observons qu'après quelques jours dans un nouveau sprint, notre build devient souvent instable et reste instable jusqu'à la fin du sprint "commit stop". L'effet néfaste de cela est que les étapes de construction loin dans le pipeline, en particulier les tests UI / Web ne sont pas exécutés pendant plusieurs jours (car ils ne sont déclenchés que sur une construction «verte»). Par conséquent, les bogues nouvellement introduits ne sont souvent détectés que très tard dans le sprint.
- Chaque validation est vérifiée par rapport à un ensemble de tests de base. Une fois vérifié, le changement est poussé à maîtriser après une revue de code (Gerrit)
- Les tests unitaires de base s'exécutent toutes les 30 min, durée inférieure à 10 min
- Les tests d'intégration s'exécutent toutes les 2h, durée 1h
- UI- / Webtests exécutés sur des tests d'intégration réussis, durée plusieurs heures
Selon qui est responsable de la stabilité de la construction pendant le sprint (cette responsabilité est transmise par sprint), il peut y avoir des "arrêts de validation" intermédiaires et ad hoc pour ramener la construction à stable.
Donc, nous voulons:
- Nos équipes de développement pour développer et valider des changements au cours d'un sprint sans entrave
- Notre processus de construction à abandonner si une étape de construction échoue, car les résultats de construction ultérieurs ont peu de sens
- Notre processus de construction pour fournir aux développeurs des commentaires de qualité en temps opportun
Étant donné (2), les points (1) et (3) semblent se contredire. Quelqu'un a-t-il une bonne pratique pour gérer cela?
( Nous relâchons actuellement le point (2) et autorisons la poursuite de la construction même en cas d'échec de la construction. Je n'ai pas encore de commentaires sur la façon dont cela influence notre qualité )
Merci Simon
la source
several hours
c'est le vrai problème. cela signifie que la solution combinée est trop grande et trop large. Vous devez chercher à composant la solution, puis disposer de petits morceaux de code sous forme de packages (disponibles d'une manière ou d'une autre dans toutes les langues principales sur toutes les plateformes). Ainsi, tout changement irait aux composants uniquement et sera détecté beaucoup plus rapidement. La construction complète consistera essentiellement à assembler des composants déjà combinés et sera également plus rapide. Vous ne pourrez alors éventuellement exécuter que quelques tests pour vous assurer que les bons composants ont été résolus.Réponses:
Quelques principes de base en premier: - Les changements majeurs doivent toujours être sur une branche de fonctionnalité dans votre VCS - Les branches de fonctionnalité doivent passer tous les tests avant de fusionner dans le tronc. Ajouté - Les commits doivent toujours se construire - Une construction cassée nécessite une action immédiate de la part du committer et / ou du reste de l'équipe. - Un test ayant échoué ne doit interrompre les tests restants que s'il s'agit d'un test critique .
Si vous, en tant qu'équipe, suivez ces pratiques et les appliquez, par exemple: "nom et honte" lorsque la version est interrompue, alors vous devriez être prêt à aller car tous les commits qui pourraient interrompre la version seront sur une branche de fonctionnalité. Les autres validations qui interrompent la génération devront être traitées immédiatement, puis vous obtiendrez vos résultats de test en aval.
Vous pouvez également ajouter un test automatique de la dernière version "réussie", (pas nécessairement celle qui réussit les tests d'intégration), pour les tests UI / Web comme une exécution de nuit rapportant la première chose le matin.
la source
N'a rien à voir avec Scrum. Votre build doit être stable en permanence, peu importe.
Personne ne devrait rien archiver à moins d'avoir effectué une construction locale et exécuté les tests unitaires localement (et les deux réussis, bien sûr). Votre processus de génération et de test local doit être sensible aux modifications et peut ignorer les tests de code qui n'a pas changé.
Toute personne qui introduit quelque chose qui entraîne l'échec de la génération ou l'échec d'un test unitaire doit être publiquement honteuse . Si la construction est cassée, elle doit être corrigée immédiatement.
la source
Votre problème semble être que les tests sont trop longs à exécuter. Heureusement, la loi de Moore nous a fourni une solution à ce problème. Aujourd'hui, les processeurs de serveur haut de gamme peuvent facilement avoir plus de 10 cœurs (et plus de 10 HyperThreads). Il peut y avoir plusieurs processeurs de ce type sur un même ordinateur.
Si j'avais des tests qui prennent autant de temps, je résoudrais le problème avec plus de matériel. J'achèterais un serveur haut de gamme, puis paralléliserais les tests afin que les tests profitent pleinement de tous les cœurs de CPU. Si vos tests sont aujourd'hui mono-thread, tirer parti de 10 cœurs et 10 HyperThreds rend probablement les tests 15 fois plus rapides. Bien sûr, cela signifie qu'ils utilisent également 15 fois la mémoire, de sorte que l'ordinateur doit avoir suffisamment de RAM.
Ainsi, les quelques heures se transformeront en 10-30 minutes.
Vous n'avez pas dit combien de temps prend la construction, mais les outils de construction standard tels que make permettent de paralléliser également la construction. Si vous parallélisez vos tests unitaires et qu'un ordinateur de développeur typique possède 4 cœurs et 4 HyperThreads, les moins de 10 minutes de tests unitaires se transformeront en moins de 2 minutes. Donc, peut-être pourriez-vous appliquer une politique selon laquelle tout le monde devrait exécuter les tests unitaires avant de s’engager?
À propos de l'échec des tests arrêtant d'autres tests: ne faites pas cela sur le serveur de build! Vous voulez autant d'informations que possible sur l'échec, et d'autres tests pourraient révéler quelque chose d'important. Bien sûr, si la construction elle-même a échoué, vous ne pouvez pas exécuter de tests unitaires. Si le développeur exécute des tests unitaires sur sa propre machine, vous souhaiterez peut-être abandonner au premier échec.
Je ne vois aucun lien entre Scrum et vos problèmes. Les problèmes peuvent vraiment se produire avec n'importe quel processus de développement.
la source
N'est-il pas possible d'avoir plus d'installations Jenkins et de demander aux développeurs de vérifier une instance Jenkins distincte?
Je pense que la meilleure solution ici est de faire passer le code à tous les tests avant qu'il ne soit archivé dans la branche master et compilé / testé par l'instance principale de Jenkins. Ne laissez pas les gens archiver du code qui rompt la construction.
Je vérifie mon code dans la branche de développement, vois s'il passe les tests et crée une demande de pull. Mais vous pourriez évidemment demander à jenkins de tirer une branche de fonctionnalité et de la tester.
la source
Le point (2) semble être le point le plus douloureux, je vais donc me concentrer sur cela.
Il serait peut-être temps de diviser le projet en plusieurs modules.
https://en.wikipedia.org/wiki/Dependency_inversion_principle
Si un module ne parvient pas à se construire, la construction des autres modules pourra continuer, tant que ces autres modules peuvent dépendre d'une interface et que le code qui compose cette interface a été construit avec succès.
Cela vous donnera des informations sur les autres échecs de génération susceptibles de se produire, afin que vous ayez le temps de réparer plus d'un module cassé avant la prochaine génération.
En général, les principes SOLID sont conçus pour traiter les problèmes de bibliothèques et de génération. En d'autres termes, cet ensemble de principes est conçu pour résoudre le type exact de problèmes auxquels vous êtes confronté.
En remarque (voir la réponse de juhist), vous ne pouvez pas accélérer la construction (par parallélisation) si vous ne partitionnez pas la construction en modules séparés.
la source
Je pense que votre équipe manque l'un des principes clés de la mêlée: terminé, logiciel fonctionnel. Un PBI ne doit pas être marqué comme terminé tant qu'il n'a pas atteint la définition de Terminé établie par votre équipe. La définition de Terminé est différente pour chaque équipe, mais inclurait probablement des éléments comme:
Donc, essentiellement, ce qui se passe, c'est que votre équipe marque des choses comme qui ne le sont pas . C'est un problème en soi.
En dehors de cela, cela se résume à une bonne gestion du contrôle de version. Si vous utilisez Git, alors tout le travail est effectué dans le référentiel local du développeur et ils ne devraient rien pousser à distance à moins qu'il ne soit "terminé" et potentiellement libérable. Un travail incomplet ne doit jamais être poussé vers votre référentiel principal. Si le développeur doit travailler sur une branche de fonctionnalité plus longue et veut pousser à distance pour s'assurer qu'il ne perd pas son travail, alors il devrait travailler à partir d'une fourchette, et vous fusionneriez alors cette fourche en main lorsque le fonctionnalité est "terminée" et potentiellement libérable - pas avant.
Pour TFVC, c'est un peu plus compliqué car tout se passe sur "à distance". Cela signifie que les développeurs devraient donc toujours travailler hors des succursales, à moins que ce ne soit une solution rapide. Les mêmes règles s'appliquent ici qu'avec Git, cependant: les logiciels incomplets ne sont pas validés. Période. Dans le contrôle de version correctement géré, "main" doit toujours être libérable. Si un commit a été fait qui borks est "principal", alors vous ne le faites pas correctement.
la source