Das Buchungsportal der Nordlicht Reisen GmbH wächst. Aus einem Build mit Tests ist eine Kette geworden: bauen, auf zwei Betriebssystemen testen, in die Entwicklungsumgebung ausliefern, in die Produktion ausliefern, danach ein Bericht, der immer erscheint, auch wenn etwas schiefging. Sie sollen die Pipeline so schreiben, dass die Reihenfolge stimmt, was parallel laufen darf, wirklich parallel läuft und eine rote Stufe nicht zu einer Auslieferung führt. Das ist die Fähigkeit dieser Lektion: Pipelines in YAML entwickeln, mit Reihenfolge der Jobs, Parallelität und mehrstufigen Pipelines.
Vorwissen: Den Aufbau mit trigger, pool, stages, jobs und steps kennen Sie aus K3, Lektion 3.7.2, den eines Workflows aus K3, Lektion 3.7.1, und wann ein Lauf startet aus Lektion 4.1. Hier geht es um das, was zwischen den Stufen und Jobs passiert.
Nicht gegen Azure oder GitHub ausgeführt; aus der Referenz von Microsoft und GitHub: Alle YAML-Dateien dieser Lektion stammen aus der Dokumentation oder sind aus ihr abgeleitet; sie sind in diesem Kurs nicht ausgeführt worden.
Azure Pipelines: Stufen, Jobs und Schritte
Microsoft beschreibt drei Ebenen. Ein Schritt ist die kleinste Einheit (script, bash, pwsh, task). Ein Job ist eine Folge von Schritten, die als Einheit auf einem Agent läuft, und die kleinste Einheit, die geplant werden kann. Eine Stufe (stage) ist eine logische Grenze, an der Sie die Pipeline anhalten und Prüfungen vornehmen können, und enthält Jobs; eine Stufe darf bis zu 256 Jobs haben. Jede Pipeline hat mindestens eine Stufe, auch wenn Sie keine schreiben.
Stufen und ihre Reihenfolge
Stufen laufen standardmäßig nacheinander, in der Reihenfolge der Datei. Mit dependsOn bilden Sie einen Graphen. Mindestens eine Stufe muss ohne Abhängigkeit sein.
stages:
- stage: Test
- stage: DeployUS1
dependsOn: Test
- stage: DeployUS2
dependsOn: Test
- stage: DeployEurope
dependsOn:
- DeployUS1
- DeployUS2
DeployUS1 und DeployUS2 laufen nach Test parallel (Auffächern, fan-out), DeployEurope wartet auf beide (Zusammenführen, fan-in). Mit dependsOn: [] löst sich eine Stufe von der davor stehenden und läuft parallel zu ihr. Ein pool auf Stufenebene gilt für alle Jobs der Stufe, sofern ein Job keinen eigenen nennt.
Zwei Schlüsselwörter sind für die Auslieferung nützlich: trigger: manual an einer Stufe, damit sie nicht automatisch startet, sondern von Hand angestoßen wird, und isSkippable: false, damit niemand eine Stufe überspringen kann, zum Beispiel die Prüfung auf Schadsoftware, die eine Vorlage in jede Pipeline einfügt. Und eine Grenze, die Prüfungen gern übersehen: YAML-Pipelines kennen keine Warteschlangen-Richtlinien (queuing policies). Jeder Lauf ist unabhängig von den anderen; zwei Commits starten zwei Läufe, die dieselbe Folge von Stufen ohne Rücksicht aufeinander durchlaufen. Microsoft empfiehlt, die Reihenfolge, wenn sie zählt, mit manuellen Freigaben zu steuern (Lektion 4.7).
Jobs in einer Stufe
Mehrere Jobs einer Stufe laufen standardmäßig parallel, solange kein dependsOn steht. Aber: Jeder Agent führt nur einen Job zur selben Zeit aus. Für wirkliche Parallelität brauchen Sie mehrere Agents und genügend parallele Jobs der Organisation (Lektion 4.2). Wer drei Jobs ohne Abhängigkeit schreibt und einen parallelen Job hat, sieht sie nacheinander laufen.
jobs:
- job: InitialA
steps:
- script: echo hello from initial A
- job: InitialB
steps:
- script: echo hello from initial B
- job: Subsequent
dependsOn:
- InitialA
- InitialB
steps:
- script: echo hello from subsequent
Der vollständige Aufbau eines Jobs zeigt, was Sie hier steuern: dependsOn, condition, strategy (mit parallel oder matrix, beides zusammen ist ein Fehler, maxParallel gilt nur mit matrix), continueOnError, pool, workspace, container, timeoutInMinutes, cancelTimeoutInMinutes, variables, steps und services. Dazu der Deployment-Job (deployment: statt job:), den Lektion 4.7 und 4.8 behandeln, und der Server-Job (pool: server), der keinen Agent braucht und nur wenige Aufgaben wie Delay, InvokeRESTAPI und ManualValidation kennt.
Zeitgrenzen: timeoutInMinutes begrenzt die Laufzeit eines Jobs. Ohne Angabe gelten 60 Minuten; 0 bedeutet die größtmögliche Grenze, und die ist unbegrenzt auf selbst gehosteten Agents, 360 Minuten bei gehosteten Agents in öffentlichen Projekten und 60 Minuten bei gehosteten Agents in privaten Projekten ohne zusätzlich gekaufte Kapazität. Ein Wert über der Grenze des gehosteten Agents wirkt nicht. Die Zeit vor dem Start (Warten auf einen Agent) zählt nicht mit.
Arbeitsverzeichnis: Auf selbst gehosteten Agents bleibt das Arbeitsverzeichnis zwischen Läufen erhalten (außer dem Ordner für Artefakte und Testergebnisse); mit workspace: clean: outputs | resources | all räumen Sie auf. Auf gehosteten Agents ist jeder Job frisch. Ob der nächste Job auf demselben Agent läuft, ist nur sicher, wenn der Pool genau einen passenden Agent hat.