Wie füreinander gemacht?

Azure DevOps und GitHub – eine gute Kombination für Entwickler
Keine Kommentare

Open-Source-basierende Softwareentwicklung ist mittlerweile aus dem Entwickleralltag kaum noch wegzudenken, sei es als Konsument oder Produzent von Open-Source-basierenden Projekten. Der Platzhirsch unter den Plattformen für diese Projekte ist mit Abstand GitHub. GitHub ist mittlerweile so etwas wie das Synonym für Open Source und Git. Die Bedeutung und Reichweite der Plattform hat auch Microsoft erkannt, im letzten Jahr die Gunst der Stunde genutzt und GitHub übernommen. GitHub wird dabei ähnlich wie LinkedIn und Minecraft als eigenständige Tochter weitergeführt.

Gerade im Entwicklerkontext sieht man hier aber einen gewissen Konflikt, stand doch Microsofts hauseigene DevOps-/ALM-Plattform Azure DevOps, bis vor wenigen Monaten noch bekannt als VSTS und TFS, stets im Wettbewerb mit den anderen Plattformen wie GitHub oder GitLab. Nicht nur der Kauf von GitHub war ein klares Bekenntnis in Richtung Open-Source-Kultur, sondern auch die aktive Unterstützung von Open-Source-Projekten durch Azure-DevOps-basierende Services (auch jenseits von Azure DevOps bzw. GitHub). In Ausgabe 3.19 des Windows Developer wurde bereits teilweise über die Neuigkeiten und Änderungen im Rahmen des Rebrandings von VSTS/TFS zu Azure DevOps und die Nutzung von Git eingegangen. Der aktuelle Artikel sieht seine Schwerpunkte bei den Fragestellungen „Wie kann man gut Open Source auf GitHub machen?“, „Was gibt es dabei zu beachten?“ und „Wie kann man sinnvoll GitHub-basierende Open-Source-Entwicklungen mit einzelnen Azure DevOps Services aufwerten?“.

GitHub und Azure DevOps

Bevor es in etwaige Details geht, gilt es zunächst Begrifflichkeiten, grobe Gemeinsamkeiten und auch Unterschiede aus der Vogelperspektive zu klären.

Wie zuvor angemerkt, wird GitHub gern als Synonym für Git als das dezentrale Versionskontrollsystem für Open-Source-Projekte verwendet. Festzuhalten gilt, dass GitHub selbst nicht der Erfinder bzw. Ursprung von Git ist. Seine Ursprünge hat Git in der Linux-Kernelentwicklung, und der Erfinder ist Linus Torvalds. Git selbst kann problemlos auch ohne GitHub oder andere Plattformen genutzt werden. Es ist seit seinem ersten Auftreten als dezentrales Versionskontrollsystem konzipiert worden. Jedes Git Repository (Container für die Artefakte) auf einem Rechner enthält stets die komplette Historie, und Entwickler veröffentlichen ihren Code und andere Dateien in dieses lokale Repository. Anschließend kann der Entwickler seine Änderungen mit anderen Git Repositories abgleichen (Git-Kommandos: Pull, Push, Fetch). Der Austausch dieser Informationen benötigt dabei nicht zwingend eine zentrale Plattform, d. h. ein Abgleich kann über diverse Kommunikationskanäle wie z. B. über einen eigenen Webserver, Windows Fileshare oder auch eine Linux-SSH-Verbindung erfolgen. Das Problem im Internet ist dabei, dass diese Arten von Austausch nicht immer sonderlich komfortabel sind.

An dieser Stelle ist GitHub eingesprungen und hat über die Zeit den De-facto-Austauschpunkt für Git Repositories im Internet geschaffen. Es speichert dort komplette Git Repositories auf die gleiche Art und Weise wie lokal und stellt sie über verschiedene Protokolle (HTTP, SSH) wieder zur Verfügung. Der Entwickler spart sich also den 24/7-Betrieb eines Servers. Zusätzlich hat GitHub neben dem reinen Hosting von Repositories seine Plattform noch um Werkzeuge zur Zusammenarbeit ergänzt. Beispiele hierfür sind Git-Repository-Suche, Codesuche, ein einfach nutzbarer Issue Tracker, Wiki, Analysewerkzeuge oder auch Unterstützung von isolierter Entwicklung mittels Forks. Forks ermöglichen die Anfertigung einer komplett isolierten Repository-Kopie. Der Nutzer von Quell- und auch Klon-Repositories wird dabei von GitHub durch diverse Funktionen unterstützt, Codeänderungen in den isolierten Repositories zu identifizieren und effizient und kontrolliert auszutauschen. Schaut man sich den Funktionsumfang von GitHub genauer an, dann fällt auf, dass GitHub sich auf Kernfunktionalitäten konzentriert. Alles was nicht zum Kernbereich gehört, kann über offene Schnittstellen von Externen nachgerüstet werden. Durch diese Offenheit hat sich ein starkes Ökosystem an freien und kommerziellen Partnerlösungen etabliert (GitHub Marketplace, Abb. 1). Hier ist es wie bei anderen Marketplace-Systemen auch: Man hat die Qual der Wahl, eine passende Lösung für sein Problem zu finden. Das ist aber auch ganz charmant, da wir ja als Entwickler/-innen nicht ein bereits gelöstes Problem noch einmal lösen wollen.

 

Abb. 1: GitHub Marketplace

Abb. 1: GitHub Marketplace

 

Diese offenen Schnittstellen sind gerade im Kontext von Azure DevOps bzw. dessen Teil-Services extrem wichtig. Auch wenn GitHub jetzt ein Microsoft-Tochterunternehmen ist, muss und soll das Azure-DevOps-Team nur die offiziellen GitHub-Schnittstellen nutzen. Microsoft bekommt hier also keine Vorzugsbehandlung in Form von eigenen inoffiziellen Schnittstellen, sondern ist aus Erweiterungssicht nur ein weiterer Partner. Das bedeutet aus GitHub-Nutzersichtweise, dass man einzelne Azure DevOps Services nutzen kann, aber nicht muss. GitHub bzw. Azure DevOps wird den Nutzer weder zu der einen noch zu der anderen Plattform noch den einen oder anderen Services drängen, sondern der Nutzer wählt je nach Problemstellung die passende Lösung.

Azure DevOps war vorher bekannt als Team Foundation Server (TFS) bzw. die Cloud-Variante unter dem Namen Visual Studio Team Services (VSTS), und verfolgt im Gegensatz zu GitHub den Ansatz, den kompletten Applikationslebenszyklus von der Anforderung bis zur Auslieferung zu unterstützen. Historisch bedingt ist das Produkt mit dem Ansatz „Best of Suite“ (alles aus einer Hand) gestartet. Mit der Umbenennung zu Azure DevOps kann auch von „Best of Breed“ (Beste Lösung in einer Nische) gesprochen werden, d. h. der Nutzer kann selektiv einzelne, für ihn sinnvolle Module benutzen und nicht so sinnvolle Module durch Fremdlösungen ersetzen bzw. ergänzen. Azure DevOps selbst besteht aus den Teil-Services Azure Boards, Azure Pipelines, Azure Artifacts, Azure Test Plans und Azure Repos. Einen Überblick zu den Anwendungsbereichen zeigt Abbildung 2.

 

Abb. 2: Überblick Services in Azure DevOps

Abb. 2: Überblick Services in Azure DevOps

 

Im Zusammenspiel mit GitHub sind die folgendern Services am interessantesten: Azure Pipelines, Azure Boards und Azure Artifacts. Azure Pipelines ist mit Abstand der wichtigste Service, da Microsoft die Build- und Release-Engine für Open-Source-Projekte kostenlos zur Verfügung stellt. Die gehostete Lösung funktioniert sowohl auf Windows, Linux als auch Mac. Kostenlos gibt es zehn parallele Build- und Release-Jobs. Aus diesem Grund wird dies auch einen inhaltlichen Schwerpunkt dieses Artikels bilden.

Arbeiten auf GitHub

Wer zuvor noch nichts mit Open-Source-Entwicklung zu tun hatte und für den GitHub auch neu ist, der wird sich erst einmal die Frage stellen, wie die Entwicklung dort eigentlich abläuft. Die wichtigste Voraussetzung, die ein Entwickler mitbringen muss, ist ein sicherer Umgang mit Git. Dabei ist es egal, ob der er gerne auf der Kommandozeile arbeitet oder eine der vielen Git-Anwendungen, z. B. TortoiseGit mit einer Oberfläche verwendet. Auch GitHub unterstützt hier Neueinsteiger, um schnell starten zu können, sei es durch den eigenen Desktopclient oder durch Anzeigen der Befehle, die für jeden einzelnen Schritt in der Entwicklung ausgeführt werden müssen. Doch bevor gestartet wird, stellt sich die Frage: Möchte ich mein eigenes Projekt bereitstellen oder lieber bei einem schon bestehenden Projekt mitwirken?

Wer sein eigenes Projekt als Open Source auf GitHub entwickeln möchte, kann bequem ein eigenes Repository erstellen und seinen lokalen Code hochladen (git push). Durch die dezentrale Art und Weise von Git ist es sehr einfach, seinen Code inklusive Historie zu teilen. Einmal in GitHub angekommen, haben jetzt andere die Möglichkeit, am Projekt mitzuwirken. Doch wer möchte wirklich, dass fremde Leute, die man unter Umständen gar nicht kennt, einfach ohne weitere Kontrolle Code ändern können? Im einfachsten Fall benötigen Externe zunächst eine Schreibberechtigung auf das Repository. Um Reviews und eine parallel risikofreie Arbeit zu unterstützen, werden Änderungen typischerweise nicht direkt im Master-Branch, sondern in Feature-Branches vorbereitet. Wenn sie abgeschlossen sind, werden sie durch „Mergen“ in den Master-Branch übernommen (git merge).

Um diesen Prozess einfacher zu gestalten, bietet GitHub die Möglichkeit, dass Code über einen sogenannten Pull Request in einen Branch bzw. ein Repository fließen kann. Bei einem Pull Request stellt ein Entwickler eine Anfrage an einen anderen Branch oder ein anderes Repository, seine Änderungen in einen bestimmten Branch zu übernehmen. Je früher dabei der Pull Request gestellt wird, desto besser, denn so können frühzeitig schon andere Entwickler Feedback geben. Nimmt man zum Beispiel den Linux-Kernel und dessen Entwicklungsprozess als Vorlage, kommen neue Änderungen nur in den Code, indem ein Entwickler sie in seinem lokalen Repository erstellt und bei jemand anderem anfragt, den Stand in sein Repository zu übernehmen (pullen).

Um es Entwicklern leicht zu machen, Änderungen an einem Repository durchzuführen, ohne vorher eine Anfrage auf Schreibberechtigung zu stellen, können in GitHub sogenannte Forks erstellt werden. Ein Fork ist eine Kopie des Repositories, das man bearbeiten möchte. Diese Kopie wird dann unter dem eigenen Account auf GitHub gehostet. Dadurch ergibt sich eine zusätzliche Trennung zwischen den beiden Repositories, denn jeder kann für sich arbeiten, und sobald der Code zurückgeführt werden soll, kann einfach ein Pull Request gestellt werden. Das hat auch den Vorteil, dass man so sein eigentliches Repository nicht mit vielen Feature-Branches zumüllt, wenn viele Entwickler gleichzeitig an Änderungen arbeiten.

Wird ein Pull Request gestellt, sollte das Entwicklerteam auch diese Anfragen aktiv managen. Pull Requests sind nicht nur da, um eine Trennung zu schaffen, sondern auch, um bequem Code Reviews durchzuführen. Dabei werden im Pull Request alle Änderungen aufgeführt, und ein Verantwortlicher (Maintainer) des Repositorys kann entscheiden, ob die Änderungen zusammengeführt (git merge) werden oder nicht. Auch können zusätzliche Checks eingebaut werden, um z. B. die Kompilierbarkeit des Codes oder die Codequalität automatisch zu prüfen.

Um es Entwicklern leicht zu machen, Änderungen an einem Repository durchzuführen ohne vorher eine Anfrage auf Schreibberechtigung zu stellen, können in GitHub sogenannte Forks erstellt werden.

Wer an einer Änderung arbeitet, für den gilt im Normalfall: Je öfter die Änderungen gespeichert (git commit) werden, desto besser. Da dies durchaus mehrmals am Tag passieren kann, entsteht für jede Änderung eine lange Historie, die mit übernommen wird. Wer nach einem Pull Request seine Historie lieber sauber halten möchte, hat noch die Möglichkeit einzustellen, ob ein Stand vorher per Squash Merge zusammengeführt wird. Bei einem Squash Merge werden alle Änderungen des Pull Request in eine einzelne Änderung zusammengefasst. Das führt dazu, dass man nicht viele kleine Änderungen mit in sein Repository übernimmt, die im Normalfall sowieso niemanden interessieren, sondern ein Pull Request auch immer eine Änderung in der Historie darstellt. Zusätzlich bekommt man dadurch eine geradlinige Historie, da die Branches mit separaten Änderungen nicht mehr auftauchen.

Wer für den Entwicklungsprozess und das Branching bei GitHub eine Vorlage braucht, kann sich an verbreiteten Ansätzen wie GitHub-Flow bzw. GitFlow orientieren. In diesen Konzepten wird erklärt, wie das Branching-Konzept aussieht und was Schritt für Schritt nötig ist, um an einem Projekt zu arbeiten. Wer sich das Leben einfacher machen möchte, wählt hier am besten ein sehr pragmatisches Branching-Konzept wie z. B. den leichtgewichtigen GitHub Flow. Für viele Projekte reicht es bereits, einen Master-Branch für den aktuellen Stand und Feature-Branches für Neuentwicklungen zu haben. Die Auswahl eines komplexen Models wie GitFlow ist gern der erste favorisierte Kanditat im Firmenkontext, aber gerade in der Zusammenarbeit mit Externen ist leichtgewichtiger besser. Sie wollen ja Externe integrieren und nicht durch ein komplexes Konzept abschrecken.

Ist erst einmal geklärt, wie Code wieder in das Repository zurückfließt, kann auch schon gearbeitet werden. Doch an was genau können andere Entwickler arbeiten? Die Stärke von Open Source ist nicht nur, dass man im Offenen entwickelt, sondern auch, dass jeder Entwickler, der möchte, sich beteiligen kann. Das schafft man, indem sowohl Requirements als auch Bugs in den öffentlich verfügbaren Issue Tracker von GitHub eingetragen werden.

Um den Planungsprozess für größere oder interne Teams besser handhabbar zu machen (Beispiel Sprint-Planung, Roadmap, Milestone-Planung über Features etc.) empfiehlt es sich, den GitHub Issue Tracker durch eine parallele Welt in Azure Boards zu ergänzen. Diese bietet die Möglichkeit, ein Backlog mit Hierarchie für z. B. Features und Requirements (sogenannte Work Items) anzulegen, aber auch eine Sprint-Planung durchzuführen. Gilt es Vertraulichkeit z. B. bei kritischen Bugs zu wahren, können diese in Azure Boards dank umfangreicherer Berechtigungen besser gesteuert werden.

Durch die geschickte Kombination von für Externe einfach zugreifbare Bugs und Requirements über GitHub Issues als auch die mächtigen Planungswerkzeugen in Azure DevOps kann man einen guten Spagat zwischen Planbarkeit und Mitarbeit ohne Hürden erreichen. Das Ziel muss hier trotz aller Bemühungen sein, dass Externe schnell und einfach mitarbeiten können. Das gilt nicht nur für Code, sondern auch für die Erfassung und Bearbeitung von Bugs und Requirements. Durch den einfachen Zugriff auf Bugs und Requirements in GitHub können auch andere Entwickler Arbeit übernehmen (sogenannte up-for-grabs Issues) und sich schnell und unkompliziert in das Projekt einbringen. Für den Fall, dass Sie als Team bevorzugt intern planen, sollten Sie dennoch die wichtigsten internen Features, Requirements etc. in Form von Tracking Issues anlegen, sodass Externe diese wichtigen Events verfolgen können.

Wer eine Dokumentation für sein Projekt hat, kann sie sowohl im Azure DevOps Wiki oder im GitHub Wiki ablegen. Beide Wikis basieren auf Markdown, um die Dokumentation im Wiki zu formatieren. Vom Aufbau sind beide relativ ähnlich und bieten die gleichen Features sowie einen Onlineeditor, mit dem man einfach die Seiten bearbeiten kann. Wer bereits viele Projekttätigkeiten über GitHub realisiert, wird sich leichter tun, auch das Wiki direkt in GitHub zu verwenden. Das sorgt auch dafür, dass nicht an zwei Stellen gesucht werden muss und GitHub dadurch zur zentralen Anlaufstelle des Projekts wird.

Ein gerne ignoriertes Wiki-Feature in beiden Projekten ist der Git Clone Support für das Wiki. Dabei kann das gesamte Wiki als eigenständiges Git Repository heruntergeladen und mit eigenen Tools bearbeitet werden. Das Wiki- und das Projekt-Repository sind dabei zunächst einmal getrennte Einheiten. Um beide Repositories wieder zusammenzuführen, kann das Wiki Git Repository als Submodul im Projekt-Repository hinzugefügt werden. Durch Submodule kann von einem Repository auf andere Repositories verwiesen werden. Beim Abrufen werden dabei beide Repositories geklont und beim Push auch wieder zurückgespeichert. Das Submodul verhält sich dabei lokal wie ein Ordner, in dem Markdown-Dateien hinzugefügt, bearbeitet und gelöscht werden können.

 

Abb. 3: Prüfung des Repositories auf Community-Standards

Abb. 3: Prüfung des Repositories auf Community-Standards

 

Nach diesen Schritten sollte das Wichtigste für das erste eigene Projekt auf GitHub erklärt worden sein. Doch wie überall gibt es noch den ein oder anderen Best Practice, an den man sich halten sollte. Auch diesen Prozess unterstützt GitHub durch diverse Tools. Ein Beispiel für ein solches Tool ist das Community Profile unter Insights (Abb. 3). Wer sich andere Repositories anschaut, wird schnell darauf stoßen, dass jedes Projekt noch weitere Dateien beinhaltet, wie eine Readme, eine Lizenzvereinbarung und eine Contributing Guideline. Eine Readme ist Pflicht und sozusagen die Startseite eines Projekts, da diese immer als Erstes auf der Projektseite angezeigt wird. Die Readme sollte kurz beinhalten, worum es in dem Projekt geht und wie es Projekt lokal erstellt werden kann.

Die Lizenzvereinbarung ist wichtig, da sie festhält, wer den Code des Projekts wie verwenden darf. Wer nicht weiß, welche Lizenz für ihn am besten passt, kann sich an anderen Projekten orientieren oder bei Choose A License eine passende Lizenz aussuchen. Hier gilt: Je leichtgewichtiger desto besser, weshalb Lizenzen wie MIT oder Apache weit verbreitet sind. Gerade im Firmenkontext sollten etwaige Lizenzen intern abgestimmt sein. Es gilt dabei allerdings zu beachten, dass gerade in Open-Source-Projekten Unterstützung von Externen gewünscht ist und diese nicht durch eine zu restriktive Lizenz abgeschreckt werden sollen. Zeigen Sie hier lieber Mut zu einer leichtgewichtigen Lizenz und weniger Angst vor Abkupfern durch Mitbewerber oder entgangenen Gewinnen.

Die Contributing Guideline beschreibt den Entwicklungsprozess und was genau getan werden muss, um sich am Projekt zu beteiligen. Sie kann außerdem den Verhaltenskodex (Code of Conduct) beinhalten, der darauf eingeht, wie sich Unterstützer des Projekts verhalten müssen, um eine angenehme Arbeitsumgebung für jeden zu schaffen. Wer gegen den Verhaltenskodex verstößt, kann durch das Projektteam vom Projekt ausgeschlossen werden.

Für Open-Source-Projekte ist noch interessant, wer die Rechte am Code besitzt. Wer möchte, dass andere Entwickler sich am Projekt beteiligen können, sollte wissen, dass die Rechte am beigesteuerten Code bei dem entsprechenden Entwickler liegen. Wenn er also seine Rechte nicht abtritt, kann er durchaus die Löschung seines Codes anweisen. Aus diesem Grund haben größere Projekte in der Contribution Guideline einen Abschnitt, den jeder Entwickler unterzeichnen muss, bei dem er die Rechte an seinem Code an das Projekt oder die Organisation hinter dem Projekt abtritt. Wer Probleme dabei hat, seine eigene Contribution Guideline oder den Code of Conduct zu definieren, kann bestehende Vorlagen von GitHub verwenden. Diese befinden sich im Projekt unter Insights im Menüpunkt Community (Abb. 3). Hier können zusätzlich auch noch Issue Templates und Pull Request Templates erzeugt werden. Diese geben eine grobe Richtlinie oder Checkliste vor, was ein Benutzer zu beachten hat, wenn er einen Pull Request oder ein Issue erstellt.

CI/CD mit Azure Pipelines und GitHub

Nachdem das Projekt in GitHub entsprechend der Community Guideline mit einer passenden Lizenz, Issue Tracking, Wiki, Source-Control-Struktur etc. aufgesetzt sowie Mitarbeiter hinzugefügt worden sind, fehlt noch ein wichtiger Punkt im Projekt, eine CI/CD-Pipeline. Continuous Integration (CI) bedeutet das regelmäßige Übersetzen der Artefakte, nachdem das Source-Control-System die Änderung gespeichert bzw. integriert hat. Durch die regelmäßige Integration werden typischerweise früher Fehler entdeckt und korrigiert. Continuous Delivery schließt sich direkt an CI-Prozesse an und erweitert den Rahmen auf das Ausliefern der Artefakte in die Produktion. Nutzer sollen die erzeugten Bits und Bytes nicht erst nach Monaten, sondern zeitnah in die Hände bekommen. Produktion als Begriff ist hier recht vielfältig. Es kann im einfachsten Fall ein Download auf der Webseite ein, aber auch die neue Version einer App im Store oder ein ausgelieferter Microservice. Auch hier ist, wie bei CI, das Ziel, möglichst schnell Feedback zu bekommen, aber diesmal direkt vom Anwender durch Nutzung der neuen Funktionalitäten. Ähnlich wie es viele verschiedene Varianten von Compilern gibt, so ist auch die Welt der CI/CD-Plattformen vielfältig.

 

Abb. 4: Azure Pipelines mit GitHub verbinden

Abb. 4: Azure Pipelines mit GitHub verbinden

 

Abb. 5: YAML-basierte Azure-Pipeline-Definition anlegen

Abb. 5: YAML-basierte Azure-Pipeline-Definition anlegen

 

Azure DevOps hat, wie eingangs erwähnt, Mitte des vergangenen Jahres die Hand Richtung Open-Source-Communities ausgestreckt. Im Rahmen des Azure DevOps Rebrandings werden Open-Source-Projekten kostenlos dem Azure Pipeline Service für CI/CD-Pipelines zur Verfügung gestellt. Das Angebot umfasst dabei die Ausführung von zehn parallelen Jobs in den Hosted Agent Pools von Microsoft. Microsoft betreibt Hosted Pools auf Windows-, Linux und MacOS-Basis sowie einige Varianten davon mit Containersupport. Alle diese Pools können Open-Source-Projekte uneingeschränkt im Rahmen von zehn parallelen Jobs in allen möglichen Kombinationen frei nutzen. Open-Source-Projekte können dabei Azure Pipelines unabhängig von den anderen Azure DevOps Services nutzen. Fehlt in Microsoft-Agent-Umgebungen eine Komponente oder ein Programm, können diese über eigene Skripte nachinstalliert werden. Es gilt hier aber zu beachten, dass die Hosted Agents immer wieder nach der Ausführung zurückgesetzt werden, sodass vertrauliche Daten von anderen Nutzern nicht aus Versehen veröffentlicht werden.

Gerade im Kontext von GitHub-Projekten hat Microsoft einiges an Arbeit in die Integration von Azure Pipelines in die Plattform investiert. Azure Pipelines lässt sich ohne Azure-Portal-Zugriff direkt über den GitHub Marketplace kaufen. Abbildung 4 und Abbildung 5 zeigen den Prozess der Integration mit GitHub und das Erstellen eines Build-Prozesses in Azure Pipelines. Wie in vielen aktuellen App-Store-System üblich, kauft der Nutzer Azure Pipelines als kostenlose Variante für 0 € (Achtung: Die kostenlose Option gilt nur für Open-Source-Projekte). Anschließend wird der Nutzer durch den Provisionierungsprozess auf die GitHub- und Azure-DevOps-Seite gelenkt. Durch das Kaufen der Extension kann der Nutzer eine neue Azure DevOps Organisation (früher bekannt als TFS Team Project Collection bzw. VSTS Tenant) anlegen. In dieser Organisation wird wiederum ein öffentliches Teamprojekt angelegt. Historisch bedingt waren bei TFS/VSTS bis Mitte 2018 nur private Projekte möglich. Für die kostenlosen Build Agents muss das Projekt aber öffentlich sein. Beim Anlegen über GitHub werden bereits durch den automatisierten Einkaufsprozess alle Services bis auf Azure Pipelines deaktiviert. Sie haben als Ergebnis quasi ein minimales Azure-DevOps-Team-Projekt. Soll dies später aufgestockt werden, ist in den Einstellungen eine Aktivierung der anderen Services möglich. Beim Anlegen der Organisation und Teamprojekte sollte man möglichst auf eine gute Benennung achten. Technisch ist es zwar kein Problem, beides zu ändern, aber als Nicht-Azure-DevOps-Nutzer sind ggf. die Optionen nicht so leicht zu finden.

Kostenlos: Azure-DevOps-Spickzettel

Jetzt herunterladen und mit wenigen Befehlen das Kommando über Azure DevOps übernehmen!

Download for free

Sind Sie bereits Azure-DevOps-Nutzer, empfiehlt es sich, eine getrennte Organisation und ein getrenntes Teamprojekt für Open-Source-Projekte anzulegen, um klar kenntlich zu machen, dass ggf. Informationen in diesen Projekten komplett öffentlich verfügbar sind. Wäre beispielsweise die Produktivinstanz „windev“, dann könnte die neue Organisation für das öffentliche Teamprojekt den Namen „windev-public“ tragen. Ob man jetzt ein Azure-DevOps-Teamprojekt für jedes GitHub Repo anlegt oder nicht, ist Geschmackssache. Empfehlenswert als Orientierung ist es, zunächst mit einem Teamprojekt für eine GitHub-Organisation zu starten und später bei Bedarf weiter zu verfeinern. Innerhalb des Teamprojekts haben Sie die gewohnten Strukturen wie Teams, Dashboards, Ordner etc. zur Verfügung, um ggf. Build- und Releaseprozesse sowie die anderen Artefakte nach Bedarf weiter zu strukturieren.

Gerade langjährigen Nutzern der TFS/VSTS-Plattform fällt auf, dass der Build-Prozess ein wenig anders aussieht. Legt man als Anwender einen Build für ein Git Repo an, ist als neuer Standard mittlerweile ein YAML-basierender Build vorausgewählt (der grafische Modus steht aber noch zur Verfügung). YAML Builds werden im Gegensatz zur grafischen Build-Variante als Code direkt im Repository gepflegt (Abb. 6). Dieser Code zeichnet sich dadurch aus, dass YAML im Gegensatz zu JSON und XML nochmals minimalistischer angelegt wurde. In diesen neuen YAML-Dateien beschreibt man Build-Schritte und Variablen sowie die Trigger, die auf diese Definition reagieren sollen (Bsp.: Pull Requests, Commits auf Master-Branch oder anderen Branches). Ein Repository kann dabei mehre YAML-Definitionen z. B. für unterschiedliche Branches enthalten. Der Integrationsprozess von einer YAML-Definition mit Standardnamen (azure-pipelines.yml) im Root Directory des Git Repos ist für Azure Pipelines weitestgehend ein Klick-weiter-Prozess. Für Powernutzer ist bei der Einbindung von mehreren YAML-Definitionen ein wenig manueller Aufwand notwendig. Hierzu legt man zunächst einen Build als Rumpf in Azure Pipelines an und passt anschließend den Pfad zur eigenen YAML-Datei händisch an.

 

Abb. 6: Beispiel für einen YAML-basierenden Build-Prozess

Abb. 6: Beispiel für einen YAML-basierenden Build-Prozess

 

Zwei Punkte sind im Kontext der öffentlich einsehbaren Build-Definitionen recht spannend: Versionierung und Handhabung von vertraulichen Informationen.

Versionierung von Programmen ist ein für sich genommenen sehr subjektiver Bereich. Über die unterschiedlichen Strategien der Versionsnummererzeugung bzw. über das Pro und Contra einer beliebten Strategie wie Semantic Versioning zu diskutieren, würde den Rahmen des Artikels sprengen. Um den Prozess technisch umzusetzen, kann man auf eine Vielzahl von Extensions im Visual Studio Marketplace zurückgreifen, um Versionsnummern zu erzeugen und Artefakte passend zu modifizieren. Ein kontrovers diskutiertes Thema ist dabei immer, wo die erzeugte Versionsnummer abzulegen ist. Es gibt hier zwei unterschiedliche Meinungen: nur im Build-Prozess oder fest eingecheckt in der Versionskontrolle. Im Build-Prozess gibt es dazu typischerweise eine oder mehre Variablen, um eine drei- oder vierstellige Versionsnummer vorzugeben. Die letzte Stelle wird meist von der Build Engine in Form einer Revisionsnummer erzeugt, sodass jeder Build-Lauf eine eindeutige Version erzeugt. Je nach Ansatz und App-Szenario (siehe Semantic Versioning) kann der Ansatz durchaus auch andere Attribute verwenden, um eine eindeutige Kennung zu erzeugen (Beispiel wäre -preview als Suffix bei NuGet-Paketen). YAML-Dateien haben hier den Charme, dass diese Basisversion als textbasierende Variable in der YAML-Datei abgelegt werden kann und somit direkt Teil des jeweiligen Branches im Repository und gleichzeitig der CI/CD-Engine ist. Dieser Ansatz ermöglicht es auch externen Entwicklern, bei wichtigen Änderungen die Basisversionsnummer direkt im Entwicklungs-Branch zu ändern und die Änderung schnell und transparent in den jeweiligen Ziel-Branch zurückzuführen. Ebenfalls ermöglicht es dieser Ansatz, schnell die aktuelle Basisversion des Branches zu identifizieren, da diese ja stets als direkt lesbarer Code vorliegt.

Auch in Open-Source-Projekten gibt es vertrauliche Artefakte, die in einem geschützten Raum verbleiben sollten. In diese Kategorie fallen solche Dinge wie z. B. Code-Signing-Zertifikate, Access Keys, Lizenzschlüssel oder Log-in-Daten. Vertrauliche Informationen sollten zunächst einmal nicht Teil des regulären öffentlichen Repositorys sein. Die Einbindung in das Projekt sollte über parametrisierbare Skripte erfolgen, sodass je nach Kontext der Build-Prozess oder Entwickler von außen die gleiche Logik verwenden, aber vertrauliche Informationen konsequent aus dem öffentlichen Repository gehalten werden können. Dank der vorgesehenen Parameter können Build-/Release-Prozesse oder Entwickler auf unterschiedliche nichtöffentliche Quellen für die vertraulichen Daten verweisen. Das Abstrahieren von vertraulichen Daten ist mittlerweile wichtiger als je zuvor, da mit solchen Daten Angreifer ggf. Zugriff auf kritische Systeme bekommen, wirtschaftlichen Schaden durch Buchung von Ressourcen, Reputationsschäden durch Ausgabe als eine fremde Person oder Ähnliches verursachen können. Ein bekanntes Beispiel aus diesem Bereich finden Sie auf der Webseite dev.to. Dabei wurden durch in GitHub gefundene Access Keys virtuelle Maschinen in AWS erzeugt, um Bitcoins auf fremde Kosten zu erzeugen. Eine Alternative zur Ablage von solchen Informationen wäre es z. B., bei GitHub ein privates Repository zu verwenden. In Kombination mit Azure Pipelines sind aber die Secure Files (Dateien) bzw. Variable Groups (textbasierende Daten) in der Azure Pipelines Library (Abb. 7) eine bessere Wahl. Das hat den Vorteil, dass sich dann die Azure-Pipeline-Infrastruktur um das Herunterladen, Entschlüsseln und Löschen der Daten vor und nach dem Build-Lauf kümmert. Die Daten sind dabei auch direkt vor den Nutzern geschützt, da der Service nur das Hochladen bzw. Ersetzen, nicht aber das direkte Auslesen der Daten ermöglicht. Aus Sichtweise des Build-Prozesses ist die Verwendung von Secure Files bzw. Parametern ähnlich einfach wie die Verwendung von normalen Variablen (Abb. 8). Es ist effektiv nur eine Referenz auf einen anderen Datensatz.

Abb. 7: Ablage von vertraulichen Informationen in Azure Pipelines Library

Abb. 7: Ablage von vertraulichen Informationen in Azure Pipelines Library

 

Abb. 8: Nutzung von Secure Files in YAML Builds

Abb. 8: Nutzung von Secure Files in YAML Builds

 

Nachdem die Bits und Bytes über einen YAML Build erzeugt wurden, steht noch die Veröffentlichung der kompilierten Artefakte an. Für diesen Prozessschritt bietet sich das Azure Pipelines Release Management an, weil es zum einen eine eingebaute Freigabefunktionalität besitzt und zum anderen durch die kostenlose Build-Pipeline abgedeckt ist. Die Freigabe (Starten der nächsten Phase) kann dabei manuell durch Nutzer oder automatisch über Tests oder andere automatische Diagnosewerkzeuge (z. B. in Release-Gates) stattfinden. Im Releaseprozess selbst kommt normalerweise kein Compiler mehr zum Einsatz. Hier werden eher die vorproduzierten Bits und Bytes an die Zielumgebung angepasst. Beispiele sind das Anpassen von Download-URLs, Config-Dateien, Austausch von Serveradressen oder Codesignierung. Nach der Aufbereitung werden die Bits und Bytes in die Zielumgebung transportiert. Abbildung 9 zeigt einen Releaseprozess am Beispiel der Hyper-V Extension. In der Preview-Phase wird das Release in den Visual Studio Marketplace hochgeladen, der Validierungsstatus überprüft und die Erweiterung in einige interne Produktivinstanzen werden installiert. Die internen Produktivinstanzen in diesem Beispiel dienen zur Unterstützung des Testansatzes „Eat your own dogfood“, d. h. wir als Team verwenden auch die Preview-Version als Produktivversion, sodass wir Fehler sehr früh finden. Nach der Preview-Phase kommt die Releasephase. Diese Phase wird hier nur gestartet, wenn der Product Owner das Release freigibt. Ein Release wird freigegeben, wenn definierte Qualitätsrichtlinien eingehalten wurden. Die explizite Freigabe ist dabei so etwas wie ein Sicherheitsnetz, da die Ansprüche an eine Produktivversion hoch sind. In der Releasephase ist zusätzlich neben der Store-Veröffentlichung noch eine Veröffentlichung der Binaries auf GitHub eingebaut, d. h. es werden die anpassten Releaseartefakte auf GitHub als Binaries inkl. Quellcode und Changelog der Commits abgelegt. Die Extension erzeugt dabei sogar automatisch ein von GitHub signiertes Tag des veröffentlichten Quellcodestands, sodass sich ein Release auf einen definierten Commit zurückführen lässt.

Abb. 9: GitHub-basierender Releaseprozess am Beispiel der Hyper-V Extension

Abb. 9: GitHub-basierender Releaseprozess am Beispiel der Hyper-V Extension

 

Der einzige Wermutstrophen bzgl. Releasemanagement ist, dass man Stand Januar 2019 diesen Prozess noch nicht als codebasierende YAML-Datei ablegen kann. Es liegt allerdings die Vermutung nahe, dass diese Lücke zeitnah geschlossen wird.

Fazit

Wie eingangs erwähnt, ist Open Source heute allgegenwärtig. Dabei spielen die Größe und auch die Organisation, die hinter einem Projekt steht, keine Rolle. Wer mit anderen Entwicklern kollaborieren möchte, kommt im Normalfall um GitHub nicht herum. Spätestens dann stellt sich die Frage, wie Planung, Build, Release und Dokumentation, also der ganz normale Entwicklungsprozess, ablaufen sollen.

Gerade der Service Azure Pipelines für Open-Source-Projekte ist ein interessantes Angebot, das durch Microsoft verwaltete Build Agents kostenlos zur Verfügung stellt.

Bis vor wenigen Jahren wurden diese Prozesse komplett ohne Microsoft-Entwicklungswerkzeuge abgebildet. Seit vergangenem Jahr hat Azure DevOps mehrere Schritte in Richtung GitHub gemacht. Die Frage ist jetzt nicht mehr „Erledige ich primär meine Arbeit auf GitHub oder Azure DevOps?“, sondern „Wie kann ich sinnvoll Azure DevOps Services in meine GitHub-basierende Entwicklung integrieren?“. Gerade der kostenlose Service Azure Pipelines für Open-Source-Projekte ist ein interessantes Angebot, das durch Microsoft verwaltete Build Agents für macOS, Linux und Windows kostenlos zur Verfügung stellt. Technologisch hat man dabei ebenfalls die freie Wahl bezüglich Betriebssystem, Tool, Compiler oder Build-Framework. Möchte man als Nutzer den Build-Prozess grafisch oder in YAML-Code-Form vornehmen, hat man hier ebenfalls die freie Wahl. Benötigt das Team neben den für einfache Nutzung ausgelegten Tools mehr Funktionalität, können auch hier Azure DevOps Services nach freier Entscheidung und Problemstellung einbezogen werden. Alles in allem ist die Integration von Azure DevOps in GitHub kinderleicht geworden und bringt viele Vorteile mit sich.

Zum Schluss noch die wichtigste Anmerkung für ein erfolgreiches Open-Source-Projekt in GitHub. Bei der Zusammenarbeit mit Externen gestalten Sie die Hürden bzgl. Zusammenarbeit so gering wie möglich. Eine Zusammenarbeit sollte stets einfach sein und Spaß machen. Um die Begeisterung zu unterstützen, wählen Sie beispielsweise nicht eine möglichst restriktive Lizenz oder eine komplexe Branching-Struktur. Das Vertrauen, das Sie Ihren Mitarbeitern entgegenbringen, wird sich durch eine bessere Zusammenarbeit für beide Seiten mehr als auszahlen.

Windows Developer

Windows DeveloperDieser Artikel ist im Windows Developer erschienen. Windows Developer informiert umfassend und herstellerneutral über neue Trends und Möglichkeiten der Software- und Systementwicklung rund um Microsoft-Technologien.

Natürlich können Sie den Windows Developer über den entwickler.kiosk auch digital im Browser oder auf Ihren Android- und iOS-Devices lesen. In unserem Shop ist der Windows Developer ferner im Abonnement oder als Einzelheft erhältlich.

Unsere Redaktion empfiehlt:

Relevante Beiträge

Hinterlasse einen Kommentar

Hinterlasse den ersten Kommentar!

avatar
400
  Subscribe  
Benachrichtige mich zu:
X
- Gib Deinen Standort ein -
- or -