Merci de nous faire partager votre workflow qui a le mérite d'être original (en tout cas c'est la première fois que j'en vois un de ce type) et de viser la simplicité. J'ai lu avec beaucoup d’intérêt l'article détaillé.
Si j'essaie de résumer ton approche:
Une branche par fonctionnalité
Une branche d'intégration. Ceci est justifié par le fait que la recette est couteuse et qu'il faut regrouper les fonctionnalités par lots plutôt que de tester et déployer en continu (Continuous Delivery/Deployment http://kief.com/iterations-considered-harmful.html )
Une branche de prod (master) qui suit l'intégration en fast forward
Le dev d'une fonctionnalité n'est confié qu'à une personne: ceci permet de se réaligner par rebase plutôt que par merge une fois la branche partagé grâce au push --force. Ceci incombe au développeur
Pour intégrer une fonctionnalité on passe encore par un rebase avant de merger en -no--ff dans la branche d'intégration, toujours permis par le fait qu'une branche de fonctionnalité n'est sous la responsabilité que d'une seule personne à un instant donné. Pour l'intégration elle est confié à une personne qui assume le rôle d'intégrateur.
A partir de là on peut comparer aux workflows classiques:
- Celui de la pure Continuous Integration qui impose à toute l'équipe de travailler dans la même branche et d'intégrer au fil de l'eau chaque commit
- Celui que sembliez utiliser précédemment qui repose sur le même principe avec les branches par fonctionnalité mais qui procède par merge pour un réalignement et pour l'intégration sans jamais insérer l'étape du rebasing. Votre modèle est un aménagement de ce workflow me semble t'il
- Les workflows des méthodes non agiles qui ajoutent des branches de lotissement (intégration, recette, maintenance) (le SemVer que tu évoques) et qui compose entre l'approche par feature ou la pure CI pour les branche de dev. (GitFlow en est un exemple type)
Pour les diverses interrogations que tu as soulevé:
Avec une approche par fonctionnalité, le rôle d'intégrateur n'est pas obligatoire.
L'intégration peut-être confiée au développeur en l'obligeant à se réaligner dans la branche de feature avant de réintégrer juste après.
C'est ce que vous faites en demandant de rebaser sa branche avant. Ceci est plutôt malin car ça vous permet de conserver un historique lisible (nettoyé à coup de rebase -i), condensé et le plus actualisé possible par rapport à l'effort d'intégration en comparaison d'une branche de feature qui partirait d'une version stable antérieure. La contrepartie est que si vous avez moins de souplesse dans la composition des fonctionnalités. Vous ne pouvez pas maintenir en parallèle plusieurs branches d'intégration qui activerait/désactiverait certaines d'entre elles. Mais ca ne semble pas un de vos besoins.
Pour revenir sur le rôle, avec le feature branching que vous avez choisi, vous pouvez décider d'autres stratégies d'intégration. Celle que tu évoques avec un intégrateur garant de la qualité de la branche mais aussi un workflow d'approbation basé sur une revue par ses pairs.
Encore une fois donc le rôle d'intégrateur n'est pas obligatoire.
Le souci que vous rencontrez, je suppose, est plutôt lié au effets pervers du feature branching et de l'isolement qu'il permet.
Si on ne se remet pas ajours régulièrement (à chaque commit dans la branche d'intégration) on se retrouve en face d'un big bang merge au moment de l'intégration ... que l'on préfère déléguer à une bonne poire qu'on nommera intégrateur ou dev senior pour lui faire avaler ce travail ingrat et délicat. Le big bang merge et la découverte tardive de problèmes d'intégration voire des conflits sémantiques (http://martinfowler.com/bliki/SemanticConflict.html) sont les arguments classiques des protagonistes de la pure CI (tous les commits dans la même branche).
Pour un bon résumé de cette question du big bang merge encore ce bon vieux Martin Fowler: http://martinfowler.com/bliki/FeatureBranch.html
A l'opposé les spécialiste de la gestion de conf prêchent l'inverse et souligne que le feature flipping reporte la complexité sur l'infra de CI en faisant exploser la combinatoire: http://www.cmcrossroads.com/article/agile-perspective-branching-and-merging
Enfin le feature flipping n'est tout simplement pas toujours possible.
Vaste débat !
Avec la CI, L'inconvénient est celui que tu évoques. Les commits de chaque fonctionnalité s'entrecroisent et la désactivation d'une fonctionnalité devient ardue si. La réponse de ces mêmes protagonistes de la CI est que le feature branching bien que facile en apparence est toujours la moins bonne solution. Il faut préférer agir au niveau du code, de l'architecture pour permettre d'activer/désactiver les features à l'exécution tout en conservant la même base de code (Une fonctionnalité est en général reportée, rarement abandonnée).
C'est la qu'il faut toujours se poser la question de savoir si on peut pratiquer le feature flipping (décrit ici http://martinfowler.com/bliki/FeatureToggle.html ), et pour les migrations techniques le branching by abstraction (http://martinfowler.com/bliki/BranchByAbstraction.html ) avant de se lancer dans les branches à tire-larigot.
Pour limiter cet isolement, il faut donc s'astreindre à se tenir à jour à chaque commit sur la branche d'intégration. Ca n'est pas de la pure CI (seuls les fonctionnalité prêtes sont integrée, celles en cours de dev restent isolée du flux d'intégration)
Avec une approche par merge, ceci peut être renforcée par le serveur de CI qui va déclencher un merge automatique à chaque commit dans l'intégration vers la feature et casser le build de la feature. Atlassian Stash et Bamboo permettent de mettre en oeuvre ceci et Atlassian investit pas mal là dessus, maas des exemples avec Jenkins existent aussi (http://testonsteroid.tumblr.com/post/14231829163/continuous-integration-flow ). Ceci me parait plus compliqué voire impossible avec cette approche par rebase que tu préconises étant donné que l'historique d'une feature peut-être réécrit par le serveur de build en concurrence avec le dev. Il faut donc s'en remettre à la discipline des devs dans ce cas.
Parmi tes autres interrogations, celle de la branche de maintenance.
Ceci dépend vraiment de votre méthode de projet et du contrat qui vous lie à vos clients.
Vous pouvez incorporer à la fois des corrections de bugs et des nouvelles fonctionnalité à chaque livraison si le client est prêt à l'accepter en terme de délais, que vous êtes "sûr" de la qualité de votre code. Dans ce cas vous ne conserver qu'une unique branche continue et vous réservez les branches courtes aux hotfixes que vous n'oublierez pas de réintegrer. C'est ce qui se pratiques avec les méthodes agiles (ce qui semble être votre cas puisque tu parles de sprint)
Le mot de la fin:
Le workflow universel n'existe pas. Git Flow n'est qu'un exemple et il faut d'abord poser à plat son processus de developpement avant de se plonger dans son workflow Git. On trouve à minima un workflow par approche (séquentiel, RUP/itératif, Agile/Scrum, Continuous Delivey, ...) et on doit souvent le réadapter au contexte du projet.
Les vieux dinosaures dont je suis évoqueraient ce bon vieux PGCL (Plan de Gestion de Configuration Logicielle) ou SCM Plan.
Voilà ... Merci à toi si tu as eu le courage de me lire jusqu'au bout et merci encore pour ton témoignage.
# Quelques retours ...
Posté par El Titi . En réponse au journal Git workflow, rebase, conflits et rôle d'intégrateur. Évalué à 10. Dernière modification le 03 décembre 2014 à 11:49.
Merci de nous faire partager votre workflow qui a le mérite d'être original (en tout cas c'est la première fois que j'en vois un de ce type) et de viser la simplicité. J'ai lu avec beaucoup d’intérêt l'article détaillé.
Si j'essaie de résumer ton approche:
A partir de là on peut comparer aux workflows classiques:
- Celui de la pure Continuous Integration qui impose à toute l'équipe de travailler dans la même branche et d'intégrer au fil de l'eau chaque commit
- Celui que sembliez utiliser précédemment qui repose sur le même principe avec les branches par fonctionnalité mais qui procède par merge pour un réalignement et pour l'intégration sans jamais insérer l'étape du rebasing. Votre modèle est un aménagement de ce workflow me semble t'il
- Les workflows des méthodes non agiles qui ajoutent des branches de lotissement (intégration, recette, maintenance) (le SemVer que tu évoques) et qui compose entre l'approche par feature ou la pure CI pour les branche de dev. (GitFlow en est un exemple type)
Pour les diverses interrogations que tu as soulevé:
Avec une approche par fonctionnalité, le rôle d'intégrateur n'est pas obligatoire.
L'intégration peut-être confiée au développeur en l'obligeant à se réaligner dans la branche de feature avant de réintégrer juste après.
C'est ce que vous faites en demandant de rebaser sa branche avant. Ceci est plutôt malin car ça vous permet de conserver un historique lisible (nettoyé à coup de rebase -i), condensé et le plus actualisé possible par rapport à l'effort d'intégration en comparaison d'une branche de feature qui partirait d'une version stable antérieure. La contrepartie est que si vous avez moins de souplesse dans la composition des fonctionnalités. Vous ne pouvez pas maintenir en parallèle plusieurs branches d'intégration qui activerait/désactiverait certaines d'entre elles. Mais ca ne semble pas un de vos besoins.
Pour revenir sur le rôle, avec le feature branching que vous avez choisi, vous pouvez décider d'autres stratégies d'intégration. Celle que tu évoques avec un intégrateur garant de la qualité de la branche mais aussi un workflow d'approbation basé sur une revue par ses pairs.
Encore une fois donc le rôle d'intégrateur n'est pas obligatoire.
Le souci que vous rencontrez, je suppose, est plutôt lié au effets pervers du feature branching et de l'isolement qu'il permet.
Si on ne se remet pas ajours régulièrement (à chaque commit dans la branche d'intégration) on se retrouve en face d'un big bang merge au moment de l'intégration ... que l'on préfère déléguer à une bonne poire qu'on nommera intégrateur ou dev senior pour lui faire avaler ce travail ingrat et délicat. Le big bang merge et la découverte tardive de problèmes d'intégration voire des conflits sémantiques (http://martinfowler.com/bliki/SemanticConflict.html) sont les arguments classiques des protagonistes de la pure CI (tous les commits dans la même branche).
Pour un bon résumé de cette question du big bang merge encore ce bon vieux Martin Fowler:
http://martinfowler.com/bliki/FeatureBranch.html
A l'opposé les spécialiste de la gestion de conf prêchent l'inverse et souligne que le feature flipping reporte la complexité sur l'infra de CI en faisant exploser la combinatoire:
http://www.cmcrossroads.com/article/agile-perspective-branching-and-merging
Enfin le feature flipping n'est tout simplement pas toujours possible.
Vaste débat !
Avec la CI, L'inconvénient est celui que tu évoques. Les commits de chaque fonctionnalité s'entrecroisent et la désactivation d'une fonctionnalité devient ardue si. La réponse de ces mêmes protagonistes de la CI est que le feature branching bien que facile en apparence est toujours la moins bonne solution. Il faut préférer agir au niveau du code, de l'architecture pour permettre d'activer/désactiver les features à l'exécution tout en conservant la même base de code (Une fonctionnalité est en général reportée, rarement abandonnée).
C'est la qu'il faut toujours se poser la question de savoir si on peut pratiquer le feature flipping (décrit ici http://martinfowler.com/bliki/FeatureToggle.html ), et pour les migrations techniques le branching by abstraction (http://martinfowler.com/bliki/BranchByAbstraction.html ) avant de se lancer dans les branches à tire-larigot.
Pour limiter cet isolement, il faut donc s'astreindre à se tenir à jour à chaque commit sur la branche d'intégration. Ca n'est pas de la pure CI (seuls les fonctionnalité prêtes sont integrée, celles en cours de dev restent isolée du flux d'intégration)
Avec une approche par merge, ceci peut être renforcée par le serveur de CI qui va déclencher un merge automatique à chaque commit dans l'intégration vers la feature et casser le build de la feature. Atlassian Stash et Bamboo permettent de mettre en oeuvre ceci et Atlassian investit pas mal là dessus, maas des exemples avec Jenkins existent aussi (http://testonsteroid.tumblr.com/post/14231829163/continuous-integration-flow ). Ceci me parait plus compliqué voire impossible avec cette approche par rebase que tu préconises étant donné que l'historique d'une feature peut-être réécrit par le serveur de build en concurrence avec le dev. Il faut donc s'en remettre à la discipline des devs dans ce cas.
Parmi tes autres interrogations, celle de la branche de maintenance.
Ceci dépend vraiment de votre méthode de projet et du contrat qui vous lie à vos clients.
Vous pouvez incorporer à la fois des corrections de bugs et des nouvelles fonctionnalité à chaque livraison si le client est prêt à l'accepter en terme de délais, que vous êtes "sûr" de la qualité de votre code. Dans ce cas vous ne conserver qu'une unique branche continue et vous réservez les branches courtes aux hotfixes que vous n'oublierez pas de réintegrer. C'est ce qui se pratiques avec les méthodes agiles (ce qui semble être votre cas puisque tu parles de sprint)
Le mot de la fin:
Le workflow universel n'existe pas. Git Flow n'est qu'un exemple et il faut d'abord poser à plat son processus de developpement avant de se plonger dans son workflow Git. On trouve à minima un workflow par approche (séquentiel, RUP/itératif, Agile/Scrum, Continuous Delivey, ...) et on doit souvent le réadapter au contexte du projet.
Les vieux dinosaures dont je suis évoqueraient ce bon vieux PGCL (Plan de Gestion de Configuration Logicielle) ou SCM Plan.
Voilà ... Merci à toi si tu as eu le courage de me lire jusqu'au bout et merci encore pour ton témoignage.