Azure DevOps Tipps und Tricks: Work-Items automatisch verschieben

Die Schritt-für-Schritt-Anleitung, wie du mit Power Automate einen Flow zur automatischen Verschiebung von Work-Items in andere Swimlanes anlegst.

Azure DevOps Tipps und Tricks: Work-Items automatisch verschieben

Auf dem Azure DevOps (ADO) Board visualisieren Swimlanes den Status von Arbeitspaketen (Work-Items) in mehreren Dimensionen. Leider bietet ADO noch keine native Möglichkeit, Regeln basierend auf den Swimlanes zu konfigurieren. In diesem Artikel zeigen wir dir, wie du mittels Power Automate Work-Items automatisch in eine Swimlane namens Testing verschieben lassen kannst, wenn das Item entsprechend getaggt wurde. Wird das Tag entfernt, wandert das Item wieder in die Default-Swimlane. Das erspart dir und deinem Team manuelle Arbeit und hält Euer Board up-to-date.

Vorschau 1: Ausgangssituation mit dem Work-Item “Example 3” ohne Tags in der Default-Swimlane.
Vorschau 1: Ausgangssituation mit dem Work-Item “Example 3” ohne Tags in der Default-Swimlane.
Vorschau 2: Das Item wurde mit “Testing” getaggt und automatisch in die Testing-Swimlane geschoben.
Vorschau 2: Das Item wurde mit “Testing” getaggt und automatisch in die Testing-Swimlane geschoben.

Voraussetzungen

  • Du brauchst eine Power Automate Premium License.

1) Flow und Trigger konfigurieren

Logge dich in Power Automate ein und erstelle einen neuen Flow, indem du My flows -> New flow klickst und Automated cloud flow wählst.

Vorschau 3: Erstellen eines neuen Flows.
Vorschau 3: Erstellen eines neuen Flows.

Im nächsten Fenster, wähle den Flow-Trigger When a work item is updated und klicke auf Create:

Vorschau 4: Auswahl des Flow-Triggers.
Vorschau 4: Auswahl des Flow-Triggers.

Das öffnet den Flow-Editor. Falls du das bisher noch nicht gemacht hast, musst du zunächst Power Automate in deinem Namen Zugang zu ADO gewähren (via OAUTH).

2) Trigger-Bedingung anpassen

Auf der Flow-Editor-Seite ist der Trigger ganz oben bereits als ein auswählbarer Block zu sehen. Wähle deine ADO-Organisation als Organization Name und den für deinen Flow relevanten Project Name. Wenn du es gerne noch genauer haben möchtest, kannst du zusätzlich die Werte für Team NameArea PathIteration Path etc. setzen.

Wähle dann Product Backlog Item als Type oder lasse das Feld leer, falls du den Flow unabhängig vom Ticket-Typ für jedes geänderte Work-Item triggern möchtest.

Generell sollte man immer in den Flow zusätzliche Bedingungen einfügen, um sicherzustellen, dass dieser nur durch das gewünschte Work-Item getriggert wird. Dadurch werden unnötige Durchläufe des Flows sowie die Zahl der HTTP-Anfragen an ADO minimiert. Das ist aber nicht Inhalt dieses Artikels.

Vorschau 5: Der Trigger im Flow-Editor.
Vorschau 5: Der Trigger im Flow-Editor.

Klicke New step um fortzufahren.

3) Variablen konfigurieren

Einige Informationen des Work-Items, das den Flow triggert, müssen wir für den weiteren Gebrauch speichern. Dazu erstellen wir für die folgenden Daten jeweils eine Variable:

  • die aktuelle Swimlane des Items (in Power Automate wird diese als Board Lane bezeichnet),
  • die Tags,
  • eine Platzhalter-Variable für die ADO-interne Swimlane-Referenz und
  • allgemeine ADO-Projektinformationen.

3.1) Die aktuelle Swimlane

Im Choose an operation Fenster, gebe variable ein und wähle unter Actions die Option Initialize variable.

Vorschau 6: Auswahl einer Variablen-Operation.
Vorschau 6: Auswahl einer Variablen-Operation.

Klicke auf die drei Punkte rechts vom neuen Variablenblock, wähle rename und gib einen möglichst sprechenden Bezeichner um den Flow übersichtlich zu halten. Du kannst auch eine Beschreibung hinzufügen, falls du diesen noch klarer machen möchtest.

In unserem Beispiel verwenden wir CurrentSwimLane als Name, aber du kannst jeden beliebigen Variablennamen verwenden. Als Type wähle String und unter Value, klicke auf Add dynamic content und wähle Board Lane aus.

Vorschau 7: Initialisierung der Variablen “CurrentSwimLane”.
Vorschau 7: Initialisierung der Variablen “CurrentSwimLane”.

Dies speichert die aktuelle Swimlane des triggernden Work-Items in der Variable CurrentSwimLane.

3.2) Tags

Füge einen weiteren initialize variable-Block mit Name = TagsType = String hinzu. Als Value, wähle Tags im Dynamic content aus.

Vorschau 8: Initialisierung der Variablen “Tags”.
Vorschau 8: Initialisierung der Variablen “Tags”.

3.3) Interne Swimlane-Referenz

An der Stelle könnte man denken, dass die Swimlane doch direkt über die Dynamic content-Variable Board Lane geändert werden kann. Allerdings ist diese read-only und kann daher leider nicht verwendet werden. Deshalb müssen wir einen kleinen Trick anwenden und eine interne Boardlane-Referenz verwenden, die für jedes Board eindeutig ist.

Füge eine Platzhalter-Variable im Flow ein, um die Referenz zu speichern. Füge dazu einen weiteren initialize variable-Block in unseren Flow ein und verwende Name = SwimLaneReference oder einen anderen passenden Namen, Type = String, und lasse den Value leer.

Vorschau 9: Initialisierung der Variablen “SwimLaneReference”.
Vorschau 9: Initialisierung der Variablen “SwimLaneReference”.

3.4) ADO Projektinformationen

Man sollte nach Möglichkeit vermeiden, hartcodierte Werte in einer Flow-Logik zu verwenden. Falls sich z.B. Werte wie der Projektname ändern, müsste man dies sonst überall im Flow bearbeiten. Initialisiere deshalb drei weitere Variablen, OrgProject and Team für deine ADO-Organisation, dein Projekt und dein Team. Diese kommen in den nächsten Schritten zum Einsatz, wenn wir mit der ADO-API interagieren.

Vorschau 10: Initialisierung weiterer Projektvariablen.
Vorschau 10: Initialisierung weiterer Projektvariablen.

4) Zustände prüfen

In unserem Beispiel sind die Zustände NewDone und Removed nicht Teil der Default- bzw. Testing-Swimlanes und daher kann der Flow stoppen, wenn ein Ticket in diese Zustände versetzt wurde. Wähle dazu New step und füge eine Condition hinzu, welche alle ungenutzten Item-States der Swimlane exkludiert. Wähle State aus der Liste des Dynamic contentis not equal to als Bedingung und füge einen Status ein. Alle weiteren Bedingungen können mit Add -> Add row hinzugenommen werden.

Jetzt sollte dein Flow in etwa so aussehen:

Vorschau 11: Übersicht des Flows bis zur ersten Bedingung.
Vorschau 11: Übersicht des Flows bis zur ersten Bedingung.

Die Bedingung erzeugt zwei Branches, If yes und If no. Den No-Branch können wir ignorieren oder bei Bedarf eine Stop-Flow-operation verwenden, da der Flow für nicht passende Items nichts machen sollen. Wir konzentrieren uns im Folgenden auf den Yes-Branch.

5) Board-interne Swimlane-Referenz

Wie oben beschrieben, ist es nicht möglich, die Swimlane-Variable eines Work-Items direkt zu ändern. Wir können aber die Swimlane-Referenz durch einen API-Call unter der folgenden URL abfragen:

https://dev.azure.com/<organisation>/<project>/<team name>/_apis/work/boards/<backlog level>

Der Wert von backlog level hängt von der Board-Kategorie ab, die für den Flow verwendet werden soll. Jede Katogrie wie z.B. Backlog items oder Features hat seinen eigenen Referenzwert.

Vorschau 12: Die unterschiedlichen “backlog level”.
Vorschau 12: Die unterschiedlichen “backlog level”.

Für Backlog items lautet die URL:

https://dev.azure.com/..../_apis/work/boards/Backlog%20items.

Achte auf korrektes URL-Encoding, falls das Level Leerzeichen beinhaltet.

Die JSON-Antwort auf die HTTP-Anfrage enthält die Swimlane-Referenz unter fields -> rowField -> referenceName. Sie beginnt mit WEF.

Zurück zu unserem Power Automate Flow: Im If yes-Branch, klicke auf Add an action und suche nach Send an HTTP request to Azure DevOps. Wähle dann deine Org-Variable als Organization Name, dazu Method = GET und verwende die anderen Projektvariablen, um die Relative URI im folgenden Format zu erzeugen:

<ADOproject>/<ADO team name>/_apis/work/boards/<backlog level>

Klicke wieder auf Add an action und suche nach Set variable. Verwende die bereits definierte Variable SwimLaneReference und der zugehörige Value sollte in etwa so aussehen:

outputs('Send_an_HTTP_request_to_Azure_DevOps_(get_reference)')?['body/fields/rowField/referenceName']

Send_an_HTTP_request_to_Azure_DevOps_(get_reference) ist dabei der Titel der Operation, der die HTTP-Anfrage aus dem vorherigen Schritt beinhaltet. Beide Schritte zusammen sollten so aussehen:

Vorschau 13: HTTP-Anfrage zum Erhalt der Swimlane-Referenz.
Vorschau 13: HTTP-Anfrage zum Erhalt der Swimlane-Referenz.

6) Prüfe die Tag-Bedingung

Im letzten Schritt müssen noch Tag-basierte Bedingungen eingebaut werden. In unserem Beispiel haben wir zwei Swimlanes, Default and Testing und die folgenden beiden Anforderungen:

  1. Befindet sich ein Work-Item in der Default-Swimlane und erhält das Tag Testing, soll es in die Testing-Swimlane verschoben werden.
  2. Befindet sich ein Work-Item in der Testing-Swimlane und das Tag Testing wird entfernt, so soll es sich zurück in die Default-Swimlane verschieben.

Direkt unter unserem letzten Set variable-Block, klicke auf Add an action um eine weitere Bedingung hinzuzufügen. Verwende im ersten Feld der ersten Zeile der Bedingung den Dynamic Content Tags. Der Komparator ist contains, da ein Ticket mehrere Tags haben kann. Das letzte Feld beinhaltet den Wert Testing. Füge eine weitere Gruppe mit and und der Bedingung CurrentSwimLane is not equal to Testing hinzu. Beides zusammen erfüllt unsere erste Anforderung.

Vorschau 14: Bedingung zur Überprüfung der verwendeten Tags.
Vorschau 14: Bedingung zur Überprüfung der verwendeten Tags.

6.1) Tag hinzugefügt

Ist die Anforderung erfüllt, soll das Ticket in die Testing-Swimlane verschoben werden. Dies wird durch einen weiteren HTTP-Request an ADO veranlasst. In unserem neuen Yes-Branch, klicke auf Add an action und suche wieder nach Send an HTTP-request to Azure DevOps. Stelle den korrekten Organization Name ein und wähle PATCH als Method. Befülle die Relative URI im folgenden Format:

<ADOproject>/_apis/wit/workitems/@{triggerOutputs()?['body/id']}?api-version=7.0

Die Anfrage verwendet die ID des Work-Items, das unseren Flow getriggert hat als Dynamic content. Füge ein Headers-Feld mit dem Key Content-Type und dem Value application/json-patch+json hinzu. Der Body der Anfrage sollte im JSON-Format wie folgt aussehen:

[
    {
        "op": "add",
        "path": "/fields/@{variables('SwimLaneReference')}",
        "value": "Testing"
    }
]

Der path für die Swimlane beinhaltet unsere SwimLaneReference-Variable und der value ist der Bezeichner der Swimlane, in welche der Item verschoben werden soll. Für weitere Details, siehe die ADO API- Dokumentation. Die ganze Operation sieht wie folgt aus:

Vorschau 15: HTTP-Anfrage, um das Work-Item in die “Testing” Swimlane zu verschieben.
Vorschau 15: HTTP-Anfrage, um das Work-Item in die “Testing” Swimlane zu verschieben.

6.2) Tag entfernt

Als Letztes müssen wir noch unsere zweite Anforderung berücksichtigen. Im If no-Branch der Tag-Bedingung, füge eine weitere Bedingung hinzu und prüfe die beiden folgenden, mit and verknüpften Statements:

  • Tags does not contain Testing
  • CurrentSwimLane is equal to Testing

Füge unterhalb der Bedingung, im neuen Yes-Branch, eine weitere HTTP-Anfrage hinzu. Diese ist ganz ähnlich aufgebaut, wie die andere, bis auf den einen Unterschied, dass als value im Body der Wert Default verwendet wird. Dadurch wird das Work-Item in die Default-Swimlane verschoben.

Vorschau 16: HTTP-Anfrage, um das Work-Item zurück in die “Default” Swimlane zu verschieben.
Vorschau 16: HTTP-Anfrage, um das Work-Item zurück in die “Default” Swimlane zu verschieben.

Damit sollte der letzte Teil unseres Flows wie folgt aussehen:

Vorschau 17: Der letzte Teil des Flows in der Übersicht.
Vorschau 17: Der letzte Teil des Flows in der Übersicht.

Beachte, dass du, falls du eine kompliziertere Swimlane-Struktur hast, die Logik in unseren verzweigten Bedingungen vermutlich anpassen musst.

Abschließende Bemerkungen

  • Unser Beispiel zeigt ein Minimalsetup, ohne zusätzliche Checks, z.B. für die No-Branches oder ob überhaupt Swimlanes existieren. Denke daran, dass die Bedingungen Endlosschleifen triggern können, falls sie nicht richtig aufgebaut sind.
  • Falls du mehrere ineinander verschachtelte Bedingungen in deinem Flow verwendest, ist es besonders wichtig, auf deren korrekte Reihenfolge zu achten.
  • Einige Werte, wie StatesSwimLanes und Tags sind in diesem Beispiel hartcodiert. Vergiss nicht, den Flow anzupassen, falls du etwas in deinem ADO-Board oder -Prozess änderst.
  • Es kann zu Verzögerungen von bis zu 5 Minuten kommen, bis das Update eines Tickets den Flow in Power Automate automatisch triggert.