August 2016

Band 31, Nummer 8

DevOps – Anwenden von DevOps auf ein Softwareentwicklungsprojekt

Von Willy-Peter Schaub, Wouter de Kort , Mattias Sköld | August 2016

„DevOps ist das Zusammenspiel von Personen, Prozessen und Produkten, das es uns ermöglicht, unseren Endbenutzer fortlaufend einen Nutzen zu bieten.“ Donovan Brown im Buch „DevOps on the Microsoft Stack“ (Wouter de Kort, 2016).

Jedes DevOps-Projekt beginnt mit einer Idee, die Sie in einer Kultur des Lernens und ständigen Bietens eines Nutzens in eine Lösung umwandeln möchten. Ziel dieses Artikels ist, unsere Erfahrungen mit Ihnen zu teilen, die wir bei der Untersuchung der Implementierung einer automatisierten Releasepipeline für unsere Entwicklung, Benutzerakzeptanztests und Produktionsumgebungen gesammelt haben. Wir begleiten Sie durch eine automatisierte Releasepipeline, die Sie unangepasst übernehmen oder zur Erfüllung Ihrer Anforderungen weiterentwickeln können.

Warum haben wir uns DevOps zu eigen gemacht? Nachdem wir uns eingehend mit dem „Warum“ (Ziel), dem „Was“ (Features) und dem „Wie“ (Technologie, Code) der Entwicklung von Extensions vertraut gemacht hatten, benötigten wir eine Kultur und Umgebung, in der wir die sich rasch entwickelnde und wachsende Gruppe von Extensions erstellen, testen, freigeben und überwachen können. Das Versprechen von DevOps animierte uns, die von Visual Studio Team Services (kurz: Team Services) gebotenen Prozesse und Tools zu untersuchen und zu übernehmen. Unsere selbst organisierten und autonomen Teams wurden in die Lage versetzt, eine Kultur und Pipeline zu entwickeln, mit deren Hilfe Releasezykluszeiten von chaotischen, fehleranfälligen und arbeitsaufwendigen Tagen in Minuten verkürzt wurden. Eine ähnliche Geschichte und Erläuterung der Pipeline wird in einem anderen Artikel in dieser Ausgabe („Vom Code zum Kunden: Mehr zu DevOps für mobile Apps“) geschildert.

Für den Fall, dass Sie nicht mit den Rangers vertraut sind: Wir sind eine Community interner und externer Entwickler, die mit der Produktgruppe zusammenarbeiten, um der Entwicklergemeinde professionelle Anleitungen, praktische Erfahrungen und lückenfüllende Lösungen zu bieten. Es waren die Lücken, aufgrund derer wir anfingen, uns Extensions mit Begeisterung zu widmen.

Extensions bieten Ihnen eine Integrations- und Erweiterbarkeitsumgebung für Team Services und Team Foundation Server (TFS). Elemente von Extensions umfassen das Arbeitsaufgabenformular, Build- und Releasetasks, Widgets für Dashboards, Menüaktionen, Agile und andere Hubs. Mit ihrer Hilfe können Sie lückenfüllende Lösungen erstellen, die in das Produkt, die Benutzererfahrung und Produktivität einfließen und für eine Verbesserung sorgen.

Eine typische Extension besteht aus einer Gruppe von JavaScript-, HTML- und CSS-Dateien. Siehe den Blogbeitrag von 2015 von Willy P. Schaub, „Extensions 101 – Attempting to Visualize the Main Processing Flow“ (bit.ly/28Yfj7A). In einer oder mehreren JSON-Manifestdateien werden grundlegende Informationen, zur Extension gehörige Dateien und von der Extension bereitgestellte Beiträge beschrieben. Weitere Informationen finden Sie in der Open-Source-Beispielextension „Folder Management“, mit deren Hilfe Sie schnell einen Ordner in Ihren Team Services-Quellrepositorys aus dem Web erstellen können, ohne das Repository lokal zu klonen oder zusätzliche Tools zu installieren.

Jede Extension ist in einem JSON-basierten Manifest beschrieben, das standardmäßig „vss-extension.json“ heißt. Aus Konsistenzgründen haben wir entschieden, dass alle künftigen Extensions auf der Team Services-Projektvorlage und unser gesamten JavaScript-Code auf TypeScript basieren soll. Der Knotenpaket-Manager (Node Package Manager, NPM) dient zum Herunterladen externer Abhängigkeiten, wie z. B. der Bibliothek „Typings“, die für TypeScript IntelliSense erforderlich ist. Wir nutzen die Fähigkeit des NPM zum Definieren einer Basisgruppe von Skripts für die Initialisierung der Entwicklungsumgebung. Ein gewisses Maß an Konsistenz stellt sicher, dass Teammitglieder einfach zwischen Teams wechseln und Probleme wesentlich einfacher untersucht und behoben werden können. Außerdem werden kürzere Zykluszeiten möglich.

Manuelles Veröffentlichen einer Extension

Wenn Sie das Repository „Folder Management“ auf Ihrem lokalen Entwicklungscomputer klonen, können Sie die Extension rasch packen und in Ihrem Marketplace-Konto manuell veröffentlichen. Das geht so:

  • Verwenden Sie die NPM-Taskausführung für Skripts (bit.ly/28Qmktu), oder führen Sie die Befehle an der Befehlszeile aus.
  • Öffnen Sie die Projektmappe, und führen Sie den Setuptask aus: npm run setup. Dadurch werden die NPM-Pakete heruntergeladen, die für TypeScript erforderlichen Eingaben initialisiert und Ihre externen Abhängigkeiten am ordnungsgemäßen Speicherort abgelegt.
  • Nutzen Sie Visual Studio zum Kompilieren der TypeScript-Dateien und Generieren der JavaScript-Ausgabe.
  • Führen Sie den NPM-Task „Packen“ aus, um eine VSIX-Ausgabedatei basierend auf dem Manifest im Projekt zu erstellen.
  • Laden Sie die generierte VSIX-Datei in den Marketplace hoch, oder führen Sie „npm run publish“ aus, um Ihre Extension automatisch zu packen und zu veröffentlichen.

Doch zunächst einige Hintergrundinformationen. Team Services besteht aus isolierten Konten. Der Marketplace ist global, besteht aus Herausgebern und wird vom Katalogherausgeber (Ihnen) erstellt und verwaltet. Eine Extension wird als privat veröffentlicht und für Team Services-Konten explizit freigegeben. Alternativ kann eine Extension auch als öffentlich veröffentlicht werden, nachdem sie überprüft wurde, und für die Allgemeinheit sichtbar sein. Wir empfehlen ausdrücklich, diese oder andere Beispielextensions nicht als „öffentlich“ zu veröffentlichen, um eine verwirrende und möglicherweise schlechte Benutzererfahrung zu vermeiden.

Stellen Sie vor dem Veröffentlichen Ihrer Extension sicher, dass das Feld „publisher“ im Manifest dem Namen Ihres Marketplace-Herausgebers entspricht. Wenn Ihr Herausgeber nicht von Microsoft bestätigt wurde, können Sie eine Extension nur als „privat“ veröffentlichen. Zum Veröffentlichen Ihrer Extension über die Befehlszeile oder die NPM-Taskausführung benötigen Sie auch ein persönliches Zugriffstoken, das die Berechtigung zum Verwalten Ihres Marketplace-Herausgebers erteilt. Im Artikel zum „Veröffentlichen einer Extension im Marketplace“ (bit.ly/28SDsOM) finden Sie weitere Details.

Eine automatisierte Build- und Releasepipeline

Sobald die Gruppe der Extensions und Revisionen wächst, werden diese scheinbar einfachen manuellen Schritte rasch arbeitsaufwendig und fehleranfällig. Deshalb fingen wir an, eine automatisierte Pipeline zu entwickeln, in der Skripts und Buildtasks zum Automatisieren der manuellen Schritte verwendet werden.

Sie können Windows PowerShell und die Buildtasks über die Befehlszeile verwenden, um das Extensionmanifest zu packen und die Versionsnummer zu ändern (siehe Abbildung 1). Ausführlichere Informationen hierzu finden Sie in Artikel „Our First Steps of Embracing DevOps When Building Visual Studio Team Services Extensions“ (aka.ms/t0wfh6), der Einfachheit und Effektivität belegt.

Abbildung 1: Buildtask „Windows PowerShell“ (oben) und Buildtask „Befehlszeile“ (unten)

Tool Windows PowerShell
Argumente cha -command "(Get-Content vss-extension.json).replace('0.0.1', ('%BUILD_BUILDNUMBER%').replace('SampleData ',"))  | Set-Content vss-extension.json" rt
 
Tool tfx
Argumente extension publish –token $(PublishExtToken) –overrides-file $(ManifestOverrideFile) –share-with $(SharedAccounts)

Alternativ können Sie die Build- und Releasetasks für Extensions zum Optimieren Ihres Build- und Releaseprozesses nutzen. Der Rest dieses Artikels basiert auf dieser Extension.

Lassen Sie uns untersuchen, wie wir die Build- und Releasetasks für Extensions genutzt und eine Blaupause für alle anderen Extensionprojekte implementiert haben. Jede Extension startet in der ersten Phase der Bereitstellung mit einem isolierten Team Services-Konto. Beim Release Management werden diese Phasen als „Umgebungen“ bezeichnet. Deshalb ist bei uns von der Entwicklungsumgebung (DEV) die Rede. Die Extension durchläuft anschließend eine Reihe von Entwurfs-, Codierungs-, Feature-, Benutzererfahrungs- und Leistungsüberprüfungen in einer getrennten Benutzer- und Produktbesitzerakzeptanz-Umgebung (BETA). Ähnlich wie bei der Entwicklungsumgebung handelt es sich hier in der zweiten Phase der Extensionbereitstellung um ein isoliertes Team Services-Konto. Sobald eine Extension unsere Definition von „Fertig“ erfüllt (bit.ly/28PLYyi), wird sie im Marketplace für jedermann sichtbar bereitgestellt. Es lässt sich erkennen, dass die Phasen DEV → BETA → PROD der Releasepipeline Form annehmen.

Um das Extensionprojekt für die automatisierte Pipeline vorzubereiten, empfehlen wir die folgenden Änderungen am Extensionmanifest (siehe Abbildung 2):

  • Legen Sie Ihre Version auf 0.0.0 und Ihren Herausgeber auf eine leere Zeichenfolge fest (“”).
  • Markieren Sie die Extension als „privat“ (public: false).
  • Entfernen Sie das „galleryFlags“-Attribut.

Abbildung 2: Auszug aus der Manifestdatei

{  "manifestVersion": 1,
  "id": "FolderManagement",
  "version": "0.0.0",
  "publisher": "",
  "name": "Folder Management",
  "description": "Quickly create a folder in your Visual Studio Team
    Services source repositories from the web. No need to clone the
    repository locally or install extra tools.",
  "public": false,
  "icons": {
    "default": "images/VSO-Folder-196x.png"
  },
  "categories": [
    "Code"
  ],
  snipped rest of manifest file ...
}

Diese Werte werden während der Releasebereitstellung aktualisiert. Die Standardwerte stellen sicher, dass die Extension nicht versehentlich bereitgestellt oder öffentlich verfügbar gemacht wird.

 Das Befolgen einer einheitlichen Benennungskonvention vereinfacht die Nachverfolgbarkeit in Ihren verschiedenen Umgebungen. Wenn Sie beispielsweise während des Release die ID an Ihre Umgebung anfügen, wird „FolderManagementBeta“ zur Extension „Folder Management“, die in der Umgebung BETA ausgeführt wird.

Continuous Integration (CI) ist eine Praxis, die es Ihnen ermöglicht, dass Sie in einem Repository für die Quellcodeverwaltung über einen für die Produktion bereiten Build des aktuellsten Code verfügen (bit.ly/28OtZ8K). Dies erfolgt mithilfe eines automatisierten Builds, wobei Tests bei jedem Commit erfolgen.

Unsere Extensionprojekte werden zumeist in einem von Team Services gehosteten Git-Repository oder bei Open-Source-Projekten wie der Extension „Folder Management“ auf GitHub gespeichert. Die Pipeline startet mit einer Builddefinition, die bei jedem im Repository erfolgenden Commit ausgelöst wird. Dann erstellt die Pipeline das VSIX-Extensionpaket und löst die Releasedefinition so aus, dass sie in den Umgebungen DEV, BETA und PROD bereitgestellt wird.

Aktivieren Sie nach Möglichkeit Continuous Integration und optional Batchänderungen, um die Anzahl ausgeführter Builds zu verringern (siehe Abbildung 3).

Buildtrigger
Abbildung 3: Buildtrigger

Aufmerksame Leser werden ggf. bemerkt haben, dass unser CI-Build nur ein VSIX-Paket ausgibt und nicht die Quelldateien der Extension kopiert. Der Grund hierfür ist eines der fundamentalen Prinzipien einer Bereitstellungspipeline, gemäß dem immer nur ein Build erstellt wird. Anstatt die Extensiondateien bei jedem Bereitstellungsschritt zu kompilieren und zu packen, erfolgt am Anfang der Pipeline nur ein einziger Packvorgang mit je nach Umgebung unterschiedlichen Konfigurationen. Wir gehen so vor, damit wir absolut sicher sind, dass wir exakt dieselbe Extension in jeder der Umgebungen bereitstellen. 

Die Verwaltung der Versionen Ihrer Extension und Buildtasks ist wichtig. In Team Services hat die neueste Version Vorrang. Wenn Sie eine öffentliche und eine Betaversion derselben Extension in einem Team Services-Konto installieren, muss klar sein, welche Version aktiviert wird.

Welche Optionen gibt es für die Versionsverwaltung? Die Team Services-Entwicklertools erlauben Ihnen das Verwenden einer beliebigen dreiteiligen Versionsnummer als Ihre Extension. Hauptsächlich aus Gründen der Einfachheit und klaren Nachverfolgbarkeit haben wir uns entschieden, „Build.Buildnummer“ als unsere Versionsnummer zu nutzen (siehe Abbildung 4).

Format der Buildnummer
Abbildung 4: Format der Buildnummer

Alternativ können Sie den Task „Extensionversion abfragen“ nutzen, der Ihnen mehr Kontrolle über die Versionsnummern gibt, die Sie veröffentlichen. Dazu verwenden Sie die aktuelle Version im Marketplace und erhöhen einen bestimmten Teil jedes Mal, wenn die Extension veröffentlicht wird. Wenngleich die Nachverfolgbarkeit zwischen der Marketplace-Version und den Artefakten in Team Services verringert wird, ergibt sich für Ihre Kunden im Marketplace eine übersichtlichere sequenzielle Nummerierung.

Wie sieht es mit Selbsttests aus? Der CI-Build eignet sich auch gut für das Ausführen von u. a. Komponententests. Für die Extension „Folder Management“ erfolgen keine Komponententests, da die gesamte Logik Aufrufe an die Team Services-REST-APIs richtet. Andere Extensions, wie z. B. das Widget „Countdown“ (bit.ly/28PTCag), sehen Komponententests vor, die die Gültigkeit der Logik zum Berechnen des Zeitunterschieds prüfen. Diese Komponententests werden als Teil des Buildprozesses ausgeführt. Andere automatisierte Tests, die wir künftig hinzufügen möchten, sind Selenium-Webtests. Dadurch können wir nicht nur Komponententests ausführen, sondern auch Tests der Benutzeroberfläche automatisieren.

Abbildung 5 zeigt die Schritte im Buildprozess. Die NPM-Abhängigkeiten werden durch Ausführen von „npm install“ (1) installiert. Das Setupskript wird mithilfe von „npm exec“-Tasks verarbeitet. Alternativ können Sie NuGet und die NuGet-Wiederherstellungsaktivität verwenden. Der Task „Visual Studio-Build“ (2) erstellt anschließend die Lösung, gefolgt vom Task „Extension packen“ (3), über den das VSIX-Extensionpaket erstellt wird.

Builddefinition
Abbildung 5: Builddefinition

Optional können Sie die Herausgeber- und Extension-IDs, das Tag und den Namen so konfigurieren, dass die Manifestwerte überschrieben werden. Die Pipeline konfiguriert nur die Versionsnummer (4) als Teil des Builds. Diese wird auf die Buildnummer festgelegt, um sicherzustellen, dass jede Instanz der Pipeline eindeutig identifiziert und nachverfolgt werden kann.

Wozu dient der PowerShell-Skripttask? Zum Zeitpunkt der Verfassung war das folgende Skript zum Extrahieren der Versionsinformationen nötig (in künftigen Versionen der Entwicklertools für Extensions und Buildtasks [bit.ly/28R0oMh] wird dieses Skript nicht mehr erforderlich sein):

$bldVerD =("$env:BUILD_BUILDNUMBER").replace("$env:BUILD_DEFINITIONNAME","").Trim();
Write-Verbose "Extracted buildVersion $bldVer";
Write-Host "##vso[task.setvariable variable=ExtensionVersion;]$bldVer"

Continuous Delivery ist die Fähigkeit der Nutzung der Ausgabe der Continuous Integration zum automatischen Erstellen und Bereitstellen des neuen als funktionierend bekannten Builds in einer oder mehreren Umgebungen (bit.ly/28PWsfk). Es gibt einen feinen Unterschied zwischen Continuous Delivery und Continuous Deployment. Letztere bezieht sich auf eine einzelne Umgebung. Ein kleines Team kann z. B. nur Continuous Deployment implementieren, da jede Änderung direkt in die Produktion überführt wird. Bei Continuous Delivery bewegt sich Code durch mehrere Umgebungen bis schließlich zur Produktionsumgebung, was automatisierte Benutzeroberflächen-, Last- und Leistungstests sowie Genehmigungen einschließen kann.

Die Bereitstellung in der Entwicklungsumgebung (DEV) erfolgt vollautomatisch und häufig. Dies bedeutet, dass jeder erfolgreiche CI-Build ohne manuelle Schritte in der DEV-Umgebung bereitgestellt wird. Nach erfolgreichem Durchlaufen der DEV-Umgebung ist eine Vorabgenehmigung erforderlich, ehe die Bereitstellung in der BETA-Umgebung erfolgt (siehe Abbildung 6). Diese Phase wird vom Projektleiter oder Programm-Manager genehmigt. Schließlich erfolgt ein Vorabgenehmigungsschritt für die Veröffentlichung in der Produktion. Diese Genehmigung muss sowohl durch den Projektleiter als auch den Programm-Manager erfolgen. Der Einfachheit halber verwenden wir nur Vorabgenehmigungsschritte und automatisieren den Schritt nach der Genehmigung, da es für uns keinen Grund gibt, einen nach der Bereitstellung erfolgenden Schritt zu genehmigen, wenn anschließend keine Bereitstellung in der nächsten Umgebung stattfindet.

Releasetrigger
Abbildung 6: Releasetrigger

Abbildung 7 zeigt die Releasedefinition, die das VSIX-Extensionpaket in drei Umgebungen bereitstellt. Für die erste Umgebung, DEV (1), ist das Team zuständig, das die Extension erstellt. Die Erweiterung wird als „privat“ bereitgestellt und für ein Sandkastenkonto für die Entwicklung freigegeben.

Releasedefinition
Abbildung 7: Releasedefinition

Nachdem das Release getestet und genehmigt wurde, wird die Bereitstellung in der zweiten Umgebung, BETA (2), fortgesetzt. Die Erweiterung wird weiter als „privat“ bereitgestellt und für ein Sandkastenkonto für Benutzerakzeptanz freigegeben.

Nachdem die Benutzerakzeptanztests abgeschlossen und genehmigt wurden, wird die Bereitstellung fortgesetzt, indem der Herausgeber geändert, die Sichtbarkeit auf „öffentlich“ geändert und die Extension im Marketplace bereitgestellt wird (3).

Der Task „Extension veröffentlichen“ (4) ist der Kern des Bereitstellungsprozesses und die Geheimzutat der Pipeline. Dieser Task aktualisiert die VSIX-Datei durch Entzippen des Inhalts, Aktualisieren der Konfigurationswerte und Zippen aller Dateien. Der Task stellt die Datei dann im konfigurierten Marketplace-Herausgeberkonto bereit, z. B. im Herausgeber „alm-rangers“, der wie gezeigt für die BETA-Umgebung konfiguriert ist.

Das Tag „Extension-ID“ (5) und der Name werden überschrieben, um sicherzustellen, dass wir über eine eindeutige Instanz der Extension verfügen, die in jeder Umgebung ausgeführt wird, dass die DEV- und BETA-Extensions automatisch für die Team Services-Konten für Entwicklung und Benutzerakzeptanztests freigegeben werden und dass die DEV- und BETA-Releases privat sind.

Sie benötigen ein persönliches Zugriffstoken (6) zum Veröffentlichen einer Extension mithilfe des Tasks „Extension veröffentlichen“ oder „Befehlszeile“. Zum sicheren Speichern des Tokens können Sie eine Team Services-Dienstverbindung mit dem Marketplace einrichten. Die Verbindung definiert ein Schlüssel/Wert-Paar, bei dem der Schlüssel der Name Ihrer Verbindung und der Wert das Zugriffstoken ist.

Einige andere interessante Tasks sind u. a.:

  • Version der Extension abfragen: Überprüft den Marketplace auf die Versionsnummer einer veröffentlichten Extension. Diese Version kann in einer Variablen gespeichert und von der Pipeline zum Erstellen einer neuen Version genutzt werden, z. B. durch Erhöhen der Haupt-, Neben- oder Patchversionsnummer.
  • Extension installieren: Stellt eine Extension im Marketplace bereit, ohne sie in ein Konto zu installieren.
  • Extensions freigeben: Gibt eine private Extension für die angegebenen Konten frei.

An dieser Stelle führt die Pipeline für die Extension konsistente Build-, Pack- und Aktualisierungsvorgänge durch. Noch wichtiger ist, dass die Pipeline Umgebungen vor gängigen Fehlern schützt. Beispiele von Buildfehlern sind Fehler im TypeScript-Code oder fehlende Dateien. Die Bereitstellung misslingt, wenn die VSIX-Datei ungültig ist, der Zugriff auf Umgebungen eingeschränkt ist oder eine der genehmigenden Personen das Release ablehnt.

Zusammenfassung

Nun da Sie über eine automatisierte Build-und Releasepipeline verfügen, können Sie Ihren Entwicklungsprozess beschleunigen, Fehler aufgrund menschlicher Eingriffe verringern und insbesondere Ihre Lösungen entwickeln sowie durch laufendes Reflektieren, Messen und Hinzulernen weiter verbessern.

Aber davon erzählen wir ein anderes Mal.

Die automatisierte CI- und CD-Pipeline hat unseren manuellen und fehleranfälligen Build- und Releaseprozess für Extensions von Tagen auf Minuten verkürzt. In dieser optimierten Umgebung kann sich unserer Entwicklungsteam auf die wirklich wichtigen Dinge konzentrieren.

Die hier gezeigten DevOps-Praktiken können Sie auch in Ihren eigenen Projekte umsetzen. Team Services ermöglicht DevOps für alle Sprachen für sämtliche Plattformen, z. B. lokale, Cloud-, Hybridcloud- und mobile Lösungen. Mit Features, die die Planung, Versionsverwaltung, Buildprozesse, Bereitstellung und Überwachung Ihrer Anwendung ermöglichen, bietet Team Services alles, was Sie brauchen, um eine Idee in funktionierende Software zu verwandeln. Wir sind gespannt, wie die mit diesen Informationen ausgestattete Community Extensions zum Verbessern der Funktionalität von Team Services erstellt, während Sie sich auf Ihre DevOps-Reise begeben.

Ressourcen zu DevOps

  • Build- und Releasetasks für Extensions aka.ms/tasksforext
  • Die Extension „Folder Management“ ist auch auf GitHub unter aka.ms/foldermanagement als Beispielcode verfügbar.
  • Bibliothek mit Tools und Anleitungen für Lösungen aka.ms/vsarsolutions
  • Übersicht der Extensions für Visual Studio Team Services bit.ly/293YEOm
  • Visual Studio Marketplace bietet Extensions, Tools, Produkte und Dienste für Visual Studio, Visual Studio Team Services, Visual Studio Code und Team Foundation Server marketplace.visualstudio.com.
  • Die Visual Studio Team Services-Projektvorlage enthält alles, was Sie zum Erstellen einer Visual Studio Team Services-Extension oder eines benutzerdefinierten Build-/Releasetasks aka.ms/extensiontemplate brauchen.
  • Was ist DevOps?aka.ms/whatisdevops

 


Willy-Peter Schaub  ist Senior Program Manager bei den Visual Studio ALM Rangers im Microsoft Canada Excellence Center. Seinen Blog finden Sie unter blogs.msdn.microsoft.com/willy-peter_schaub. Sie können ihm auch auf Twitter folgen: @wpschaub.

Wouter de Kort ist der leitende Berater von Microsoft bei Ordina in den Niederlanden, wo er Unternehmen hilft, bei der Entwicklung von Software auf dem Laufenden zu bleiben. Seinen Blog finden Sie unter wouterdekort.com. Sie können ihm auf Twitter folgen: @wouterdekort.

Mattias Sköld ist ein DevOps/ALM-Coach bei Sogeti in Schweden. Er hilft Kunden beim Verbessern ihrer Software und Fördern der internen Einführung von ALM/DevOps-Praktiken bei Sogeti. Er betreibt einen Blog unter mskold.blogspot.com. Sie können ihm auf Twitter folgen: @mattiasskold.

Unser Dank gilt den folgenden technischen Experten von Microsoft für die Durchsicht dieses Artikels: Donovan Brown, Jess Houwing und Will Smythe