Empêchez les branches de s'entasser

19

Nous commençons à rencontrer un problème au fur et à mesure que nous grossissons, où les fonctionnalités arrivent au test pour le test, mais au moment où tout est testé et les nouvelles fonctionnalités approuvées sont en cours de test pour le test.

Cela crée un environnement dans lequel nous ne pouvons presque jamais pousser vers la production car nous avons une combinaison de fonctionnalités testées et non testées. Je suis sûr que c'est un problème courant, mais je n'ai pas encore trouvé de bonnes ressources pour nous.

Quelques spécificités:

  • GIT sur BitBucket
  • Jenkins pour le déploiement par script sur Azure

Ce que j'espère, c'est un moyen d'isoler les fonctionnalités au fur et à mesure qu'elles se déplacent dans les environnements et ne poussent que ce qui est prêt à produire.

Wesley
la source
1
Êtes-vous en train de créer des branches pour chaque fonctionnalité, ou de pousser les modifications de fonctionnalités directement vers la branche du serveur de test?
Robert Harvey
1
Sans informations sur la façon dont vous gérez les fonctionnalités et les branches, nous ne pouvons pas donner de réponse spécifique à vos problèmes.
Michael Durrant
2
Travaillez-vous avec les itérations d'une manière ou d'une autre (par exemple, sprints de deux semaines ou versions avec versions)?
RemcoGerlich
@RobertHarvey: Nous branchons pour chaque fonctionnalité, mais nous avons une branche Dev, Stage et Prod dans laquelle nous fusionnons qui construit et déploie automatiquement cette branche lors de la fusion.
Wesley
@RemcoGerlich: Nous travaillons actuellement sur trois semaines, mais avec huit développeurs, rien ne garantit que les progrès que nous réalisons à chaque cycle sont parfaits dans tous les domaines.
Wesley

Réponses:

22

Il semble que vous ayez quelques problèmes ici:

1. Identification des fonctionnalités d'une version spécifique

Il s'agit d'un problème de gestion de projet et d'un problème de coordination. Est-ce que cette fonction soit libéré avant, en même temps que, ou après cette autre fonction? Si les versions veulent se produire une fonctionnalité à la fois, identifiez-le. Si les fonctionnalités vont être regroupées dans des versions, déterminez quels sont les regroupements et appliquez-les aux développeurs et aux décideurs. Utilisez votre système de suivi des problèmes ou de billetterie pour baliser les versions. Expliquez clairement que si une fonctionnalité d'une version spécifique est interdite, alors toutes le sont.

2. Stratégies de branchement

Git-flow est la réponse facile à de tels problèmes, et souvent les gens utilisent une variante de git-flow même s'ils ne savent pas ce que c'est. Je ne vais pas dire que c'est un fourre-tout pour tous les problèmes, mais cela aide beaucoup.

On dirait que vous rencontrez un problème avec les stratégies de publication non déterministes, où les fonctionnalités sont approuvées en scattershot et quelque chose qui a commencé le développement il y a longtemps pourrait être publié après quelque chose qui a commencé plus récemment - les fonctionnalités de saut de grenouille.

Les branches de fonctionnalités à longue durée de vie ou les branches de versions simultanées sont probablement la meilleure réponse à ce type de problèmes. Fusionnez (ou rebasez, si vous êtes à l'aise avec) la dernière version de master dans vos branches de longue date. Faites attention à ne fusionner que les fonctionnalités déjà en ligne, sinon vous rencontrerez les problèmes que vous rencontrez actuellement (trop de fonctionnalités mélangées sur une branche).

Les branches "Hotfix" ou "bugfix" sont une partie essentielle de ce processus; utilisez-les pour de petites corrections ponctuelles qui ont un cycle d'assurance qualité court.

D'après votre description, il pourrait même être préférable de ne pas maintenir une branche officielle de «développement». Plutôt, branchez toutes les fonctionnalités hors du maître et créez des branches de versions fusionnées une fois qu'une version est identifiée.

3. Environnements

Ne faites pas correspondre les branches git à vos environnements, sauf pour la production == master. La branche «développement» doit être supposée cassée. Les branches de publication sont poussées pour tester les environnements, qu'il s'agisse d'un environnement QA ou d'un environnement de transfert. Si vous en avez besoin, envoyez une branche de fonctionnalité spécifique à un environnement.

Si vous avez plusieurs branches de fonctionnalités qui doivent être publiées séparément mais sont testées en même temps ..... ¯ \ _ (ツ) _ / ¯ .... vous lancez un autre serveur? Peut-être les fusionner ensemble dans une branche jetable ... valider les correctifs / modifications dans les branches originales et re-fusionner dans la branche jetable; faire l'approbation finale et l'UAT sur les branches de publication individuelles.

4. Suppression de fonctionnalités non approuvées d'une succursale

C'est ce que les pensées ci-dessus tentent d'éviter, car c'est sans aucun doute la chose la plus douloureuse à essayer. Si vous êtes chanceux, les fonctionnalités ont été fusionnées dans vos branches de développement ou de test de manière atomique à l'aide des validations de fusion. Si vous n'avez pas de chance, les développeurs se sont directement engagés dans la branche développement / test.

De toute façon, si vous vous préparez pour une libération et avoir des changements non approuvés, vous aurez besoin d'utiliser Git pour reculer les commits non approuvés de la branche de sortie; la meilleure idée est de le faire avant de tester la version.

Bonne chance.

Jen
la source
NB: par "cycle QA court" pour les branches de correctifs, je parle de quelque chose qui va être poussé à la production dans la journée, à peu près. Urgences. Certaines personnes ne les utilisent pas de cette façon, mais c'est ce que moi et mon équipe faisons et cela semble bien fonctionner pour nous.
Jen
annonce 1: la question a une balise "intégration continue", donc je pense que l'OP veut mettre les fonctionnalités immédiatement en production une fois testées (assez). Ainsi, le résultat des tests pourrait contrôler l'ordre de mise en production, ce qui est un peu contraire à votre recommandation.
Doc Brown
... néanmoins je pense que c'est une très bonne réponse.
Doc Brown
D'accord - J'ai supprimé le bit "commande" de la première section. Je pense que "commander" est moins important que d'identifier les versions. Si CI est l'objectif, il est certainement plus important de conserver des fonctionnalités distinctes pour les tests et les versions que de respecter un calendrier.
Jen
Je ne recommanderais généralement pas cela non plus - mais la question demandait spécifiquement d'essayer de gérer le code lorsque certaines fonctionnalités n'étaient pas testées et n'étaient pas approuvées. Je travaille rarement sur des projets qui ont tellement d'incertitude quant aux fonctionnalités qui seront publiées lorsque - généralement le calendrier de sortie est assez planifié, et un retard dans une version repousserait également la suivante. Que feriez-vous à la place?
Jen
4

Voici une idée, arrêtez d'utiliser les branches de publication. Au lieu de cela, commencez à intégrer des bascules de fonctionnalités et à les gérer via la configuration. De cette façon, vous fusionnez toujours les branches de fonctionnalités dans master et vous ne devriez jamais vous demander quelle version est en test ou en prod. Si vous avez une question sur les fonctionnalités / implémentations actives dans un environnement, vérifiez simplement le fichier de configuration.

Canard en caoutchouc
la source
3

Cela devrait être une simple question de coordination entre le test et la production. Si vous utilisez des branches de fonctionnalités dans Git, arrêtez simplement de pousser les branches de fonctionnalités terminées vers Test pendant un cycle de test et reprenez lorsque le test est terminé.

Si vous avez besoin d'un meilleur contrôle, séparez Test en un serveur de développement et un serveur de test d'acceptation, et coordonnez les branches qui seront transmises au serveur de test d'acceptation avec l'équipe de test. Quelqu'un peut alors être responsable du lancement du déploiement final du test d'acceptation à la production.

Robert Harvey
la source
2

Le travail s'accumule

C'est un problème universel dans mon expérience. Je l'aborde avec:

  • Bonne gestion des versions des fonctionnalités par le propriétaire du produit
  • Assurez-vous que les branches sont supprimées lors de leur fusion
  • Limiter le travail en cours (avec des limites de colonne dans Jira)
  • Revue trimestrielle des anciens tickets qui languissent, bugs et fonctionnalités
  • Rétrospectives pour discuter des composants du problème
  • Encouragement constant pour les révisions de code par tous
  • Opportunités de jumelage pour résoudre les problèmes et les problèmes de longue date
  • Réunions trimestrielles pour examiner et nettoyer les anciens billets
  • Approche d'équipe pour que les développeurs, les produits et l'AQ / QE travaillent en étroite collaboration
  • Bons rapports et outils pour rendre les nouvelles fonctionnalités du produit et l'arriéré évidents
  • Revoir les sessions pour parcourir les anciennes branches et les supprimer
Michael Durrant
la source
2

Branches

Vous avez besoin de quelques branches pour contrôler ce processus:

  • caractéristique : ces branches sont nées du maître. Utilisez une application de gestion de projet pour identifier chaque branche de fonctionnalité avec une tâche. Par exemple, si vous utilisez TRAC, vous finirez si des branches comme: 1234-user-crud, 1235-bug-delete-catalog, etc. Identifiez vos commits avec le numéro de tâche aussi, cela vous aidera beaucoup quand vous avez des problèmes dans les fusions (vous).
  • test : toutes les branches de fonctionnalités effectuées seront fusionnées dans la branche de test. Vous ne fusionnez jamais la branche de test dans une branche de fonctionnalité , car vous ne voulez pas de code provenant d'une autre fonctionnalité qui n'est pas dans la production (maître). Il en va de même pour la releasebranche.
  • version : lorsque vous décidez quelles fonctionnalités testées peuvent être dans la production, vous fusionnez (encore ...) ces branches dans cette branche. Vous devez tester à nouveau toutes les fonctionnalités, car cette fusion peut entraîner de nouveaux problèmes. Lorsque la version est testée et terminée, vous fusionnez cette branche à master et créez une balise sur master pour la version.
  • maître : contient uniquement le code de production.

Voir le git flow:

                              |FEAT_2|
                                  |
                             .---C06<-------.---------.
                            /                \         \
                           /   |FEAT_1|        \         \
                          /       |            \         \
                         /    .--C07<--.--------\---------\---------.
                        /    /          \        \  |TEST| \         \
                       /    /            \        \    |    \         \
                      /    /        .-----`--C09<--`--C10    \         \ |RELEASE|
                     /    /        /                          \         \    |
    <v4.6.0>        /    /        /                       .----`--C11<---`--C12<--.
       |           /    /        /                       /                         \
C01<--C02<--C04<--´----´--------´-----------------------´---------------------------`--C13
 |           |                                                                          |
<v4.5.0>  <v4.6.1>                                                                   |MASTER|
                                                                                        |
                                                                                     <v4.7.0>

Environnements

Très simple:

  • test : cet environnement utilise la branche test.
  • release : cet environnement utilise la branche de release réelle.

Les développeurs travaillent sur sa machine, chacun utilisant sa propre base de données. Si ce n'est pas possible chaque développeur a une base de données individuelle (à cause des licences, de la taille de la base de données, etc.), vous aurez beaucoup de problèmes à partager une base de données entre les développeurs: quand quelqu'un supprime une colonne ou une table dans sa branche, les autres branches compte toujours avec cette colonne / table dans la base de données.

Problèmes

Le plus gros problème de ce processus est la fusion.

Vous devez refaire les mêmes fusions dans testet release. Cela sera pénible si un bon refactorisateur est créé dans le code, comme supprimer une classe, déplacer / renommer des méthodes, etc. Comme vous ne pouvez pas obtenir le code de la branche test(ou release) dans la branche de fonctionnalité, les validations de fusion ne peuvent être résolues que dans le test(ou release). Donc, vous finissez par résoudre les mêmes conflits dans deux branches différentes, produisant probablement du code différent dans chaque fusion et, à l'avenir, vous découvrirez que l'équipe de test devra tester les fonctionnalités deux fois: dans les branches testet release, car chaque fusion peut entraîner différents bugs.

Un autre problème est la testbranche. Vous devrez "recycler" cette branche (supprimer et créer une nouvelle à partir de master) de temps en temps, car certaines anciennes branches (ou anciennes fusions, branches fusionnées qui ont été supprimées) peuvent entraîner de nombreux problèmes pour le nouveau code, divergeant beaucoup de ce qui est dedans master. En ce moment, vous avez besoin du contrôle des branches que vous souhaitez fusionner à nouveau dans letest .

La meilleure solution est que l'équipe commerciale sait ce qui doit être fourni dans la prochaine version et tout le monde travaille dans une branche unique (branche de développement). C'est bien pour eux la possibilité de choisir la fonctionnalité "terminée" qu'ils aimeraient être dans la prochaine version à tout moment (je pense que c'est votre scénario), mais c'est un cauchemar pour les développeurs et (je crois) pour le équipe de test.

Dherik
la source
@DownVoter, pourquoi?
Dherik
0

On dirait que vous fusionnez changements de votre branche d'intégration dans votre branche de production, ce qui à mon humble avis n'est pas une bonne pratique, exactement pour les raisons que vous mentionnez. Dès qu'une branche de production pour une certaine version est retirée de la branche d'intégration principale, la branche d'intégration peut, à tout moment, diverger (après tout, elle est supposée évoluer vers la prochaine version). La fusion de la branche d'intégration dans la branche de version actuelle peut entraîner des modifications incompatibles avec cette version.

À mon humble avis, un processus approprié serait:

  • retirer une branche de production de la branche d'intégration uniquement lorsqu'elle est jugée suffisamment proche du niveau de qualité souhaité, de sorte que seule une poignée de modifications devraient permettre de terminer la version. En d'autres termes, l'achèvement des fonctionnalités doit être évalué (en continu) sur la branche d'intégration, avant de tirer la branche de production.
  • une fois la branche de production retirée, seules les modifications choisies sont apportées, traitées comme des modifications autonomes / corrigées - c'est-à-dire vérifiées qu'elles fonctionnent réellement comme prévu (ce n'est pas parce qu'une modification fonctionne dans une branche qu'elle fonctionne également dans une autre branche).
Dan Cornilescu
la source
0

Personnellement, cela semble être plus un problème de processus qu'un problème d'outillage. Quelques choses que je suggérerais ici:

  • Je ne sais pas si vous avez des groupes de développement et d'assurance qualité distincts. Si vous le faites, assurez-vous que Dev et QA participent aux réunions de planification et d'estimation du sprint. Dans l'une de mes entreprises précédentes, nous nous sommes assurés que le nombre de points d'histoire que nous avons attribués à une histoire représentait à la fois des efforts de développement et de test. (Vous pouvez également théoriquement avoir deux estimations distinctes pour l'effort de développement et d'assurance qualité, mais dans les deux cas, vous avez besoin que votre estimation inclue les deux; le temps requis pour une histoire est le temps nécessaire pour la livrer réellement). Même si vous n'avez pas de groupe AQ ​​distinct, assurez-vous toujours d'inclure l'effort de test dans vos estimations.
  • Dans la même veine que ci-dessus, convenez à l'avance du nombre d'histoires que vous allez inclure dans un sprint particulier. Le nombre de points d'histoire que vous acceptez est basé sur le montant que vos développeurs peuvent terminer dans leur sprint et le nombre d'éléments que QA peut tester dans leur sprint. (Je suppose, bien sûr, que les sprints QA sont derrière les sprints Dev, mais vous pouvez l'adapter à votre processus). Si vos développeurs peuvent terminer 200 points d'histoire mais que votre AQ ne peut en terminer que 150, vous ne pouvez évidemment faire que 150 points d'histoire avant que le travail ne commence à "s'accumuler" et vous vous retrouvez avec un cas comme celui que vous décrivez. (Dans un cas comme celui-ci, vous voudrez peut-être enquêter sur la cause du barrage routier pour tenter de l'atténuer).
  • Personne ne pousse quoi que ce soit vers le contrôle qualité jusqu'à ce que tout ce qui se trouve actuellement dans le contrôle qualité soit testé et livré .
  • Une fonctionnalité complète est celle qui a été testée et livrée. S'il n'est pas livré, ce n'est pas fait.
  • De toute évidence, vous voulez essayer de le faire sur une sorte d'horaire fixe. L'une des idées derrière l'intégration continue et l'agilité est l'itération. Par définition, l'itération implique une livraison fréquente. Des intégrations et des livraisons fréquentes minimisent le risque de chacune.

Honnêtement, je pense que le plus important sera la discipline concernant le moment où vous livrez et le nombre de tâches que vous pouvez réellement terminer complètement dans un délai donné.

Pour résumer: ne livrez à QA que lorsque vous avez terminé de tester et de livrer les anciennes fonctionnalités.

EJoshuaS - Réinstallez Monica
la source
-2

Lorsque "tout est testé et approuvé", déployez ce qui a été testé et approuvé en production. Cela pourrait être un commit particulier, ou ce pourrait être un artefact de build particulier généré par Jenkins.

Peu importe que les validations ultérieures sur la même branche ne soient pas encore testées.

bdsl
la source
1
Il importe certainement que les validations ultérieures dans la même branche n'aient pas été testées et approuvées - le déploiement de code vers une production qui n'a pas été testée est un moyen infaillible d'obtenir un client en colère.
Jen
Je ne suggère pas que des commits ultérieurs soient déployés. Je dis laisser ces commits plus tard seuls, déployer celui qui a été testé.
bdsl
En d'autres termes, ignorez les branches, prenez la décision de déploiement en ce qui concerne les validations individuelles ou les builds individuels.
bdsl