Ich arbeite an einem sehr großen, von der Forschung geleiteten Open-Source-Projekt mit einer Reihe anderer regelmäßiger Mitarbeiter. Da das Projekt jetzt ziemlich groß ist, ist ein Konsortium (bestehend aus zwei Vollzeitmitarbeitern und wenigen Mitgliedern) für die Pflege des Projekts, die kontinuierliche Integration (CI) usw. zuständig. Sie haben einfach keine Zeit für die Integration von externen Mitarbeitern Beiträge aber.
Das Projekt besteht aus einem "Kern" -Framework, etwa einer halben Million Codezeilen, einer Reihe von "Plugins", die vom Konsortium verwaltet werden, und mehreren externen Plugins, von denen die meisten nicht vorhanden sind. nicht einmal bewusst.
Derzeit erstellt unser CI den Core und die gepflegten Plugins.
Eines der großen Probleme, mit denen wir konfrontiert sind, ist, dass die meisten Mitwirkenden (und besonders die gelegentlichen) nicht 90% der gepflegten Plugins erstellen. Sie überprüften, ob der Code auf ihrem Computer kompiliert wurde, bevor sie eine Pull-Anfrage für GitHub stellten.
Der Code funktioniert, sie sind glücklich, und dann ist das CI fertig und die Probleme beginnen: Die Kompilierung ist in einem vom Konsortium gepflegten Plugin fehlgeschlagen, das der Mitwirkende nicht auf seinem Computer erstellt hat.
Dieses Plugin kann Abhängigkeiten zu Bibliotheken von Drittanbietern aufweisen, z. B. CUDA , und der Benutzer möchte nicht, weiß nicht, wie oder kann dieses defekte Plugin aus Hardwaregründen einfach nicht kompilieren.
Also dann - entweder bleibt der PR ad aeternam in der Schwebe von nie zusammengeführten PRs - oder der Mitwirkende greift nach der umbenannten Variablen in der Quelle des defekten Plugins, ändert den Code, drückt auf seinen Zweig, wartet auf Wenn das CI die Kompilierung abschließt, werden in der Regel mehr Fehler angezeigt, und der Vorgang wird wiederholt, bis CI zufrieden ist.
Keine dieser Optionen ist machbar, aber wir wissen einfach nicht, wie wir es anders machen sollen. Wurden Sie jemals mit einer ähnlichen Situation Ihrer Projekte konfrontiert? Und wenn ja, wie sind Sie mit diesem Problem umgegangen? Gibt es eine Lösung, die ich hier nicht sehe?
quelle
Antworten:
CI-getriebene Entwicklung ist in Ordnung! Das ist viel besser, als keine Tests durchzuführen und kaputten Code einzuschließen! Es gibt jedoch ein paar Dinge, die dies für alle Beteiligten einfacher machen:
Festlegen von Erwartungen: Erstellen Sie eine Beitragsdokumentation, aus der hervorgeht, dass CI häufig zusätzliche Probleme findet und diese vor einer Zusammenführung behoben werden müssen. Erklären Sie vielleicht, dass kleinere lokale Änderungen mit größerer Wahrscheinlichkeit gut funktionieren. Daher kann es sinnvoll sein, eine große Änderung in mehrere PRs zu unterteilen.
Lokale Tests fördern: Erleichtern Sie das Einrichten einer Testumgebung für Ihr System. Ein Skript, das überprüft, ob alle Abhängigkeiten installiert wurden? Ein Docker-Container, der sofort einsatzbereit ist? Ein Image einer virtuellen Maschine? Verfügt Ihr Testläufer über Mechanismen, mit denen wichtigere Tests priorisiert werden können?
Erklären Sie, wie Sie CI für sich nutzen können: Ein Teil der Frustration ist, dass dieses Feedback erst nach dem Einreichen einer PR erfolgt. Wenn die Mitwirkenden CI für ihre eigenen Repositorys einrichten, erhalten sie früheres Feedback - und produzieren weniger CI-Benachrichtigungen für andere Personen.
Beheben Sie alle PRs in beiden Fällen: Wenn etwas aufgrund eines Defekts nicht zusammengeführt werden kann und keine Fortschritte bei der Behebung der Probleme erzielt werden, schließen Sie es einfach. Diese aufgegebenen offenen PRs verstopfen einfach alles, und jedes Feedback ist besser, als nur das Problem zu ignorieren. Es ist möglich, dies sehr schön zu formulieren und klar zu machen, dass Sie sich natürlich freuen würden, wenn die Probleme behoben sind. (Siehe auch: Die Kunst des Abschlusses von Jessie Frazelle , Best Practices for Maintainers: Lernen, nein zu sagen )
Erwägen Sie auch, diese verlassenen PRs auffindbar zu machen, damit andere sie abholen können. Dies kann sogar eine gute Aufgabe für neue Mitarbeiter sein, wenn die verbleibenden Probleme mechanischer Natur sind und keine tiefe Kenntnis des Systems erfordern.
Langfristig gesehen scheinen diese Änderungen die nicht zusammenhängende Funktionalität zu sprengen, was häufig dazu führen kann, dass Ihr aktuelles Design ein wenig problematisch ist. Zum Beispiel, kapseln die Plugin-Interfaces die Interna Ihres Kerns richtig ein? C ++ macht es leicht, versehentlich Implementierungsdetails zu verlieren, ermöglicht aber auch die Erstellung starker Abstraktionen, die nur sehr schwer zu missbrauchen sind. Sie können dies nicht über Nacht ändern, aber Sie können die langfristige Entwicklung der Software hin zu einer weniger fragilen Architektur unterstützen.
quelle
Um ein nachhaltiges Plugin-Modell zu erstellen, muss Ihr Kern-Framework eine stabile Schnittstelle bereitstellen, auf die sich Plugins verlassen können. Die goldene Regel lautet, dass Sie im Laufe der Zeit neue Schnittstellen einführen können, aber niemals eine bereits veröffentlichte Schnittstelle ändern können. Wenn Sie diese Regel befolgen, können Sie die Implementierung des Kernframeworks beliebig umgestalten, ohne befürchten zu müssen, dass versehentlich Plugins beschädigt werden, unabhängig davon, ob es sich um ein vom Konsortium verwaltetes oder ein externes handelt.
Nach dem, was Sie beschrieben haben, klingt es so, als hätten Sie keine genau definierte Oberfläche, und das macht es schwierig zu sagen, ob eine Änderung die Plugins beschädigen wird. Arbeiten Sie daran, diese Schnittstelle zu definieren und in Ihrer Codebasis explizit anzugeben, damit die Mitwirkenden wissen, was sie nicht ändern sollten.
quelle
Um ehrlich zu sein, glaube ich nicht, dass Sie besser damit umgehen können - wenn Änderungen dazu führen, dass verwaltete Teile Ihres Projekts beschädigt werden, sollte das CI fehlschlagen.
Verfügt Ihr Projekt über eine
contributing.md
oder eine ähnliche Funktion, die neuen und gelegentlichen Mitwirkenden bei der Vorbereitung ihrer Beiträge hilft? Haben Sie eine klare Liste, welche Plugins zum Core gehören und kompatibel bleiben sollen?Wenn es aufgrund von Abhängigkeiten usw. schwierig ist, alles auf einem Computer zu erstellen, können Sie einsatzbereite Docker-Images als Build-Umgebungen für Ihre Mitwirkenden erstellen.
quelle
Ich denke, hier kann der lockere Stil von Open Source-Projekten ins Wanken geraten. Bei den meisten zentral organisierten Projekten ist das Core Refactoring vorsichtig, insbesondere wenn es eine API-Grenze überschreitet. Wenn sie eine API-Grenze umgestalten, ist dies in der Regel ein "Big Bang", bei dem alle Änderungen gleichzeitig mit einem Inkrement zur Hauptversion der API geplant werden und die alte API beibehalten wird.
Ich würde eine Regel vorschlagen: "Alle API-Änderungen müssen im Voraus geplant werden": Wenn ein PR eingeht, der eine rückwärts inkompatible Änderung an der API vornimmt, muss jemand, der sich nicht mit den Betreuern in Verbindung gesetzt hat, seine Vorgehensweise im Voraus vereinbaren wird einfach geschlossen und der Einsender zeigt auf die Regel.
Sie benötigen auch eine explizite Versionierung der Plugin-API. Auf diese Weise können Sie v2 entwickeln, während alle v1-Plug-ins weiterhin erstellt werden und funktionieren.
Ich würde auch ein bisschen mehr fragen, warum so viele Änderungen am Core-Refactoring und an der API vorgenommen werden. Sind sie wirklich notwendig oder nur Menschen, die dem Projekt ihren persönlichen Geschmack aufzwingen?
quelle
Klingt so, als müsste der CI-Prozess straffer, umfassender und für die Mitwirkenden sichtbarer sein, bevor sie eine PR erheben. BitBucket verfügt beispielsweise über eine Pipelines-Funktion, die dies ermöglicht. Sie geben ihr eine Datei, die den CI-Erstellungsprozess im Code definiert. Wenn dies fehlschlägt, wird verhindert, dass der Zweig zusammengeführt wird.
Unabhängig von der Technologie können Sie durch das Bereitstellen automatischer Builds, wenn ein Mitwirkender zu einer Zweigstelle wechselt, viel schneller erkennen, worauf Sie beim Vornehmen von Änderungen achten müssen, und dies führt zu PRs, die nachträglich nicht repariert werden müssen.
Designprobleme lassen sich gut beheben, sind jedoch orthogonal zu diesem Problem.
quelle
Ihre Lösung ist einfach: Senken Sie die Beitragshürde .
Der einfachste Weg, um (1) den Bearbeitungs-Kompilierungs-Testzyklus zu beschleunigen und (2) Umgebungsunterschiede auszugleichen, besteht darin, Build-Server bereitzustellen :
Öffnen Sie dann diese Buildserver für Mitwirkende. Sie sollten in der Lage sein, sich remote in einem neuen Docker-Image anzumelden und den Kompilierungstest auf diesem Computer remote zu bearbeiten.
Dann:
Generell können Build-Server von mehreren Mitwirkenden gemeinsam genutzt werden. Wenn jedoch spezielle Hardware-Peripheriegeräte beteiligt sind, kann es erforderlich sein, dass ein Mitwirkender diese Peripheriegeräte selbst verwendet.
Quelle: Bei der Arbeit an Software, die FPGAs verwendet, ist angesichts des Preises der Bestien und der Vielzahl der von uns benötigten Modelle nicht jedes FPGA-Modell auf jedem Entwickler-Computer installiert.
quelle
Wenn ein Beitrag zum Kern ohne Vertragsänderung abhängige Software zum Erliegen bringen kann, schlägt dies Folgendes vor:
Beide Probleme sollten leicht zu lösen sein, Sie erwähnen jedoch, dass das Kernteam möglicherweise nicht über die entsprechenden Kapazitäten verfügt. Eine Möglichkeit wäre, die Community um Hilfe bei der Behebung des Problems zu bitten.
quelle
Niemand sonst scheint dies als mögliche Lösung angesprochen zu haben.
Fordern Sie die Entwickler bei der Entwicklung des Kerns auf, diese Kompatibilitätstests durchzuführen. Wenn sie fehlschlagen, checken Sie nicht ein.
Dadurch wird die Kompatibilität nicht zu 100% sichergestellt, aber es werden viel mehr Probleme und Probleme frühzeitig behoben.
Ein zweiter Vorteil ist, dass diese Aufzeichnungen hervorheben können, welche Schnittstellen aktiv verwendet werden und welche Funktionen aktiv verwendet werden.
quelle
Ich habe Probleme, die Situation so zu verstehen, wie sie zu sein scheint: Das CI baut nur einen Zweig auf?
Gibt es einen Grund, warum Sie mit dem CI nicht mehr als eine Filiale aufbauen können?
Die einfachste Lösung für dieses Problem besteht darin , es jedem Mitwirkenden zu ermöglichen, den CI-Build auf seinem Feature-Zweig auszuführen .
Dann benötigen Sie einfach einen erfolgreichen CI-Build für die Feature-Verzweigung, damit die Pull-Anforderung dieser Verzweigung akzeptiert wird.
quelle