Je travaille sur un très grand projet open source basé sur la recherche, avec un tas d'autres contributeurs réguliers. Étant donné que le projet est maintenant assez important, un consortium (composé de deux employés à temps plein et de quelques membres) est chargé de la maintenance du projet, de l'intégration continue (IC), etc. Ils n'ont tout simplement pas le temps d'intégrer des partenaires externes. contributions bien.
Le projet est composé d'un framework "core", d'environ un demi million de lignes de code, d'un tas de "plugins" gérés par le consortium et de plusieurs plugins externes, dont la plupart ne sont pas disponibles. t même au courant.
Actuellement, notre CI construit le noyau et les plugins maintenus.
Un des gros problèmes auquel nous sommes confrontés est que la plupart des contributeurs (et en particulier les occasionnels) ne construisent pas 90% des plugins maintenus, donc quand ils proposent de refactoriser les changements dans le noyau (ce qui se passe assez régulièrement de nos jours), ils ont vérifié que le code était compilé sur leur machine avant de faire une demande de tirage sur GitHub.
Le code fonctionne, ils sont contents, puis le CI termine la construction et les problèmes commencent: la compilation a échoué dans un plug-in mis à jour par le consortium, le contributeur n'a pas construit sur sa machine.
Ce plugin peut avoir des dépendances sur des bibliothèques tierces, telles que CUDA par exemple, et l'utilisateur ne veut pas, ne sait pas comment, ou ne peut tout simplement pas, pour des raisons matérielles, compiler ce plugin endommagé.
Alors, soit le RP reste à flot dans les limbes des RP jamais fusionnés , soit le contributeur saisit la variable renommée dans la source du plug-in cassé, modifie le code, appuie sur sa branche, attend le CI pour terminer la compilation génère généralement plus d'erreurs et réitère le processus jusqu'à ce qu'il soit satisfait - Ou l'un des deux permanents déjà surbookés du consortium donne un coup de main et tente de corriger le PR sur leur machine.
Aucune de ces options n'est viable, mais nous ne savons tout simplement pas comment le faire différemment. Avez-vous déjà été confronté à une situation similaire de vos projets? Et si oui, comment avez-vous géré ce problème? Y a-t-il une solution que je ne vois pas ici?
la source
Réponses:
Le développement piloté par CI, c'est bien! C'est beaucoup mieux que de ne pas exécuter de tests et d'inclure du code erroné! Cependant, il y a plusieurs choses pour rendre cela plus facile pour toutes les personnes impliquées:
Définissez les attentes: créez une documentation de contribution expliquant que CI trouve souvent des problèmes supplémentaires et qu'ils devront être résolus avant une fusion. Expliquez peut-être que les changements locaux modestes ont plus de chances de bien fonctionner - il est donc judicieux de scinder un changement important en plusieurs RP.
Encouragez les tests locaux: facilitez la configuration d'un environnement de test pour votre système. Un script qui vérifie que toutes les dépendances ont été installées? Un conteneur Docker prêt à l'emploi? Une image de machine virtuelle? Votre testeur dispose-t-il de mécanismes permettant de hiérarchiser les tests les plus importants?
Expliquez comment utiliser CI pour eux-mêmes: Une partie de la frustration est que ce retour d’information ne survient qu’après la soumission d’un PR. Si les contributeurs configurent CI pour leurs propres référentiels, ils obtiendront un retour plus tôt et produiront moins de notifications de CI pour d'autres personnes.
Résolvez tous les PR, dans les deux sens: si quelque chose ne peut pas être fusionné car il est cassé, et s'il n'y a aucun progrès à faire pour résoudre les problèmes, fermez-le. Ces relations publiques ouvertes et abandonnées encombrent tout, et toute rétroaction vaut mieux que de simplement ignorer le problème. Il est possible de formuler cela très bien et d'indiquer clairement que vous seriez heureux de fusionner lorsque les problèmes seront résolus. (voir aussi: L'art de la clôture par Jessie Frazelle , Meilleures pratiques pour les responsables de la maintenance: apprendre à dire non )
Pensez également à rendre ces relations publiques abandonnées découvrables afin que quelqu'un d'autre puisse les récupérer. Cela peut même être une bonne tâche pour les nouveaux contributeurs, si les problèmes restants sont plus mécaniques et ne nécessitent pas une connaissance approfondie du système.
Pour la perspective à long terme, ces modifications semblent rompre si souvent des fonctionnalités sans rapport, ce qui peut signifier que votre conception actuelle est un peu problématique. Par exemple, les interfaces de plug-in encapsulent-elles correctement les éléments internes de votre noyau? C ++ facilite la divulgation accidentelle des détails d'implémentation, mais permet également de créer des abstractions fortes qu'il est très difficile d'utiliser de manière abusive. Vous ne pouvez pas changer cela du jour au lendemain, mais vous pouvez guider l'évolution à long terme du logiciel vers une architecture moins fragile.
la source
Pour créer un modèle de plug-in durable, votre infrastructure de base doit présenter une interface stable sur laquelle les plug-ins peuvent compter. La règle d'or est que vous pouvez introduire de nouvelles interfaces au fil du temps, mais que vous ne pouvez jamais modifier une interface déjà publiée. Si vous suivez cette règle, vous pouvez reformuler tout ce que vous voulez pour mettre en œuvre le framework principal sans craindre de casser accidentellement des plugins, qu’il s’agisse d’un consortium géré par un consortium ou d’un tiers.
D'après ce que vous avez décrit, il semble que vous n'ayez pas d'interface bien définie, ce qui rend difficile de dire si un changement va casser les plugins. Travaillez à définir cette interface et à la rendre explicite dans votre base de code, afin que les contributeurs sachent ce qu’ils ne doivent pas modifier.
la source
Pour être honnête, je ne pense pas que vous puissiez gérer cela mieux. Si des modifications entraînent la rupture de parties maintenues de votre projet, le CI devrait échouer.
Votre projet a-t-il un projet
contributing.md
similaire pour aider les contributeurs nouveaux et occasionnels à préparer leurs contributions? Avez-vous une liste claire, quels plugins font partie du noyau et doivent rester compatibles?S'il est difficile de tout compiler sur une machine en raison de dépendances, etc., vous pouvez envisager de créer des images de docker prêtes à l'emploi en tant qu'environnements de construction utilisables par vos contributeurs.
la source
Je pense donc que c’est là que le style informel des projets open source peut s’effondrer; la plupart des projets organisés de manière centralisée se méfient du refactoring principal, en particulier lorsqu'il franchit une limite d'API. S'ils refacturent une limite d'API, il s'agit généralement d'un "big bang" dans lequel toutes les modifications sont planifiées en même temps avec une incrémentation de la version principale de l'API, et l'ancienne API est conservée.
Je proposerais une règle selon laquelle "toutes les modifications d'API doivent être planifiées à l'avance": si un représentant principal introduit une modification incompatible en amont de l'API de la part de quelqu'un qui n'a pas été en contact avec les responsables pour convenir à l'avance de son approche, se ferme tout simplement et le déposant a souligné la règle.
Vous aurez également besoin d'un versioning explicite de l'API du plugin. Cela vous permet de développer v2 alors que tous les plugins v1 continuent à se construire et à fonctionner.
Je voudrais également demander un peu plus pourquoi tant de modifications de refactoring et d'API sont apportées. Sont-ils vraiment nécessaires ou juste des personnes imposant leurs goûts personnels au projet?
la source
On dirait que le processus d'EC doit être plus étroit, plus complet et plus visible pour les contributeurs avant qu'ils ne génèrent un PR. Par exemple, BitBucket a une fonctionnalité de pipelines qui le permet, où vous lui donnez un fichier qui définit en code le processus de construction de l'EC, et en cas d'échec, la branche ne peut pas être fusionnée.
Indépendamment de la technologie, fournir des builds automatiques lorsqu'un contributeur pousse dans une branche leur donnera un retour beaucoup plus rapide sur ce qu'il faut surveiller lors de la modification et conduira à des PR qui n'ont pas besoin d'être corrigés après coup.
Il serait bon de résoudre les problèmes de conception, mais ils sont orthogonaux à ce problème.
la source
Votre solution est simple: abaissez la barrière à la contribution .
Le moyen le plus simple pour (1) accélérer le cycle édition-compilation-test et (2) atténuer les différences d'environnement consiste à fournir des serveurs de génération :
Et ouvrez ensuite ces serveurs de construction aux contributeurs. Ils devraient pouvoir se connecter à distance à une nouvelle image Docker et éditer, compiler-tester à distance sur cette machine.
Ensuite:
En règle générale, les serveurs de build peuvent être partagés par plusieurs contributeurs. Toutefois, lorsque des périphériques matériels spéciaux sont impliqués, il peut être nécessaire qu'un contributeur utilise ce périphérique par lui-même.
Source: travaillant sur des logiciels utilisant des FPGA, étant donné le prix des bêtes et la variété de modèles dont nous avons besoin, vous ne trouvez pas chaque modèle de FPGA installé sur chaque ordinateur de développeur.
la source
Si le fait de contribuer au cœur sans changer aucun contrat peut rompre un logiciel dépendant, cela suggère que:
L’un ou l’autre problème doit être facile à résoudre, mais vous indiquez que l’équipe centrale n’est peut-être pas en mesure de le faire. Une option serait de demander l'aide de la communauté pour résoudre le problème.
la source
Personne d'autre ne semble avoir évoqué ce problème comme une solution potentielle.
Lors du développement du noyau, encouragez les développeurs à exécuter ces tests de compatibilité. S'ils échouent, ne vous enregistrez pas.
Cela ne garantira pas la compatibilité à 100%, mais cela posera beaucoup plus de problèmes très tôt.
Un autre avantage est que ces enregistrements peuvent indiquer quelles interfaces sont activement utilisées et quelles fonctionnalités sont activement utilisées.
la source
J'ai du mal à comprendre la situation telle qu'elle semble être: l'IC ne construit qu'une seule branche?
Y a-t-il une raison pour laquelle vous ne pouvez pas créer plus d'une branche avec CI?
La solution la plus simple à ce problème serait de permettre à tout contributeur d’exécuter le build CI sur sa branche de fonctionnalité .
Ensuite, vous devez simplement disposer d'un CI réussi sur la branche fonctionnelle pour que la demande d'extraction de cette branche soit acceptée.
la source