Un de mes collègues m'a dit qu'il envisageait de faire en sorte que notre serveur CI annule les validations qui ont échoué à la génération, donc le HEAD
dans master
est toujours stable (comme en passant la génération au moins) .
Est-ce une meilleure pratique ou cela peut être plus problématique que de laisser master
cassé jusqu'à ce que le développeur le corrige?
Ma pensée est que l'annulation de la validation rendra plus complexe la tâche de relecture de la validation et du correctif (le développeur devra annuler la restauration puis valider le correctif, ce qui encombrera également le git log
) et nous devons simplement laisser la validation, puis valider le correctif. Bien que je vois certains avantages à avoir master
stable, ce retour des validations échouées ne me convainc pas.
edit: Peu importe s'il s'agit de master
ou de toute autre branche de développement, mais la question reste la même: le système CI doit-il annuler une validation qui a échoué à la génération?
une autre modification (longue): Ok, nous utilisons git
d'une manière étrange. Nous pensons que le concept de branches va à l'encontre du véritable CI, car s'engager dans une branche vous isole des autres développeurs et de leurs changements, et ajoute du temps lorsque vous devez réintégrer votre branche et faire face à d'éventuels conflits. Si tout le monde s'engage sur master
, ces conflits sont réduits au minimum et chaque validation passe tous les tests.
Bien sûr, cela vous oblige à pousser uniquement stable (ou vous cassez la version) et à programmer plus soigneusement pour ne pas casser la compatibilité descendante ou faire basculer les fonctionnalités lors de l'introduction de nouvelles fonctionnalités.
Il y a des compromis à faire CI tel ou tel chemin, mais cela est hors de portée de la question (voir question connexe pour cela). Si vous préférez, je peux reformuler la question: une petite équipe de développeurs travaille ensemble dans une branche de fonctionnalités. Si un développeur valide quelque chose qui rompt la construction de cette branche, le système CI doit-il annuler la validation ou non?
Je serais contre le faire pour les raisons suivantes:
Chaque fois que vous configurez un outil automatisé pour changer le code en votre nom, il y a le risque qu'il se trompe ou qu'une situation se produise où vous en avez besoin pour arrêter de faire ce changement (par exemple , la dernière version de Google Mock contenait un bogue, donc ce n'est pas votre code qui échoue) et vous devez perdre du temps à le reconfigurer. De plus, il y a toujours un léger risque que la construction échoue à cause d'un bogue dans le système de construction, plutôt que d'un bogue dans votre code. Pour moi, CI consiste à gagner la confiance que mon code est correct; cela ne ferait que le transformer en une autre source de problèmes potentiels dont je devrais m'inquiéter.
Les types de bugs qui cassent "la construction" devraient être des erreurs stupides qui prennent très peu de temps à corriger (comme vous l'avez indiqué dans un commentaire, cela est vrai pour vous). Si des bogues plus subtils et compliqués arrivent régulièrement sur master, alors la bonne solution n'est pas de "le réparer plus vite", c'est d'être plus prudent lors de l'examen des branches de fonctionnalités avant qu'elles ne soient fusionnées.
Laisser le maître non constructible pendant quelques minutes pendant que le bug est corrigé correctement ne fait de mal à personne. Ce n'est pas comme si le PDG vérifie personnellement le master et publie le code directement aux clients à tout moment aléatoire (du moins, espérons-le, sans votre implication). Dans le cas très improbable où vous devez publier quelque chose avant de pouvoir corriger le bogue, alors vous pouvez facilement prendre la décision de revenir manuellement avant de publier.
Entendons-nous d'abord sur les conditions.
J'utilise personnellement les termes Construction continue et Intégration continue pour distinguer deux scénarios différents:
Ce dernier, l'intégration continue, signifie que le référentiel qu'il protège est toujours vert1: c'est strictement mieux.
Votre question n'a de sens que pour la construction continue, donc je répondrai en supposant que c'est votre configuration.
1: Les causes environnementales peuvent également gâcher une construction, par exemple un test avec une année codée en dur (2015) peut commencer à échouer en janvier 2016, un disque peut être plein, ... Et bien sûr, il y a le fléau des tests instables . J'ignore hautainement ces problèmes ici; sinon nous n'irons jamais nulle part.
Si vous avez une configuration de construction continue, vous pouvez en effet automatiser l'inversion des validations qui peuvent avoir interrompu la génération, mais il existe plusieurs subtilités.
Notez qu'avec ce système, en cas de test instable ou si un collègue commet souvent de la merde, de nombreux bons commits seront annulés. Vos collègues vous détesteront alors.
J'espère que mon histoire d'horreur a révélé les problèmes d'autoriser un référentiel cassé et vous allez maintenant implémenter un pipeline d'intégration continue approprié où les RP ne sont jamais directement poussés vers le référentiel mais mis en file d'attente pour la fusion dans une file d'attente de travail, et intégrés un à la fois ( ou par roll-up):
Après avoir essayé les deux, c'est strictement mieux.
Est-ce une meilleure pratique ou cela peut être plus problématique que de simplement laisser master cassé jusqu'à ce que le développeur le corrige?
C'est problématique. Une personne décidant que "le maître HEAD est cassé; je reviendrai sur le changement supérieur" est complètement différente du système CI qui fait de même.
Voici quelques inconvénients:
Des erreurs dans le processus d'inversion automatisé visseront le référentiel;
cela suppose un seul ensemble de modifications (le plus haut) vissé la construction (ce qui est irréaliste)
Les responsables auront plus de travail à faire pour résoudre le problème, que simplement enquêter et valider (ils devront également regarder l'historique inversé)
Nous pensons que le concept de branches va à l'encontre du véritable CI, car s'engager dans une branche vous isole des autres développeurs et de leurs changements, et ajoute du temps lorsque vous devez réintégrer votre branche et faire face à d'éventuels conflits.
Cette croyance (branches vs CI) est incorrecte. Pensez à conserver n branche stable, où vous ne validez que testé unitaire ensembles de modifications. Le reste (succursales de fonctionnalités et succursales locales) devrait être de la responsabilité de chaque développeur et ne devrait en aucun cas faire partie de votre politique CI.
Dans les branches de fonctionnalités, vous voulez être isolé des autres développeurs. Cela vous permet de:
effectuer un codage exploratoire
expérimenter avec la base de code
effectuer des validations partielles (valider efficacement le code non fonctionnel) pour configurer des points de sauvegarde (au cas où vous bousilleriez), pour créer un historique des modifications plus significatif (via des messages de validation), et pour sauvegarder votre travail et passer complètement à autre chose (dans le temps qu'il vous faut pour écrire "git commit && git checkout")
effectuer des tâches de faible priorité qui prennent beaucoup de temps (par exemple, vous voulez effectuer un refactoring qui modifie les 80 classes de la couche de données: vous en changez deux par jour, jusqu'à ce que vous les changiez toutes et que le code compile (mais vous pouvez le faire sans affecter personne jusqu'à ce que vous puissiez faire un seul commit).
Si un développeur valide quelque chose qui rompt la construction de cette branche, le système CI doit-il annuler la validation ou non?
Ça ne devrait pas. La validation du code stable sur votre branche CI est la responsabilité du committer, pas un système automatisé.
Je suggère d'utiliser un environnement Gerrit + Jenkins pour garder votre branche principale toujours en bon état. Les gens poussent leur nouveau code vers Gerrit qui déclenche un travail Jenkins pour extraire ce correctif, les builds, les tests, etc. Si d'autres développeurs comme votre correctif et Jenkins terminent son travail avec succès, alors Gerrit fusionnera ce morceau de code dans votre branche principale.
C'est un environnement similaire décrit par @ brian-vandenberg
En plus de maintenir votre branche en bon état, vous ajoutez également une étape de révision du code qui améliore la qualité du code et le partage des connaissances sur votre logiciel.
[1] Jenkins https://jenkins-ci.org/
[2] Gerrit https://www.gerritcodereview.com/
Le CI ne doit jamais modifier l'historique de validation du dépôt.
La solution correcte ici est qu'aucun ajout ne soit ajouté à la branche principale s'ils n'ont pas été testés et vérifiés.
Travaillez-vous sur des branches de fonctionnalités, faites exécuter automatiquement le CI sur celles-ci, et si les builds échouent, ne les fusionnez pas dans master.
Vous pouvez avoir une version supplémentaire qui teste les fusions si celles-ci sont un problème, en s'exécutant sur la branche de fonctionnalité, et pendant la génération fusionnant maître/intégration/quoi que ce soit dans la branche locale, puis en exécutant des tests.
Nous utilisons Jenkins pour notre serveur de génération et utilisons le modèle de contrôleur d'accès pour pousser les validations - où une combinaison de Jenkins et de déclencheurs de validation (qui garantissent que les pairs examinateurs ont fait leur travail) est le contrôleur d'accès.
Les validations sont envoyées indirectement via un curl à Jenkins, où il clone le référentiel maître, puis récupère les validations à fusionner et effectue toutes les générations requises (pour Linux/solaris). Si toutes les générations sont terminées, la validation est poussée.
Cela évite de nombreux sinon tous les problèmes discutés jusqu'à présent:
Cela nous permet également d'appliquer directement d'autres exigences, telles que la réussite des tests unitaires.
La question posée est défectueuse. Je respecte cependant cette déclaration
"Nous pensons que le concept de branches va à l'encontre du vrai CI, car s'engager dans une branche vous isole des autres développeurs et de leurs changements"
Ce que vous devez faire, c'est ces étapes
ALORS, ce que nous faisons est de mettre un crochet de validation git pour empêcher TOUT LE MONDE de réellement s'engager à maîtriser. Cela fonctionne très bien .... AUCUN build cassé jamais et AUCUN rétablissement ne revient du maître non plus.
plus tard, Dean
Combien de fois avez-vous reçu cet e-mail automatisé disant que votre dernier commit a interrompu la construction? Combien de fois est-ce mal? Mais maintenant, vous devez vérifier pour voir si c'était bien vous ou quelqu'un d'autre qui a fait un autre commit à peu près au même moment. Ou peut-être que c'était quelque chose d'environnement.
Si le système n'est pas sûr, je ne veux certainement pas l'automatiser.