Mit dem TFS 2015 wurde das neue Team Build System für die OnPremise-Version eigeführt. Seitdem ist die Umstellung von XAML Builds auf das neue JSON basierte Build-Format in vollem Gange. Die Vorteile des neuen Build Systems liegen auf der Hand und müssen an dieser Stelle nicht nochmals thematisiert werden. Doch nicht nur die bestehenden Build Definitionen müssen angepasst und umgestellt werden, auch bestehende Erweiterungen für den TFS müssen für die neue Technologie fit gemacht werden. Nicht jeder kann oder will auf VSTS und seine Extensions umsteigen. Somit besteht noch immer Bedarf an großen und kleinen Erweiterungen für TFS onPremise Installationen.
Doch zurück zu dem eingangs erwähnten Umstieg vom alten auf das neue Buildsystem. Was passiert, wenn eine Erweiterung auf fertiggestellte Builds reagieren soll? Richtig, sie hängt sich an den TFS und notifiziert sich auf das entsprechende Event. Anwendungsfälle dafür könnten spezielle Benachrichtigungen, die Anbindung von externen Tools oder schlicht das Triggern weiterer Operationen über die TFS API sein. Im Grunde stellt dies keine besondere Herausforderung dar. Von Microsoft wird für derartige Anwendungsfälle das ISubscriber Interface bereitgestellt. Mit Hilfe dieses Interfaces ist es möglich, sich auf verschiedenste Events des TFS zu notifizieren.
Das Interface selbst implementiert nur zwei Properties (Name und Priority) sowie die zwei Methoden SubscribedTypes, über die alle Events definiert werden, auf die man sich notifiziert und ProcessEvent, die aufgerufen wird, sobald eines der definierten Events auftritt.
Um die Unterschiede beim Umstieg auf das neue Build-System zu verstehen, wird im ersten Schritt das alte, XAML basierte, Buildsystem betrachtet. Möchte man über fertiggestellte XAML Builds informiert werden, so muss das BuildCompletionNotificationEvent als Rückgabewert der Methode SubscribedTypes definiert werden. Innerhalb der ProcessEvent Methode kann dann die weiterführende Implementierung vorgenommen werden. Die Assembly, in der die Implementierung des ISubscriber Interfaces vorgenommen wurde, muss anschließend in dem Ordner %ProgramFiles%\Microsoft Team Foundation Server 14.0\Application Tier\Web Services\bin\Plugins abgelegt werden und fertig ist das eigene TFS Plugin.
Notifizieren auf VNext Builds
Wer jetzt denkt, das würde reichen um auch VNext Build Events abzufangen, der irrt. Diese werden nicht nur über einen eigenen Event Typ abgebildet, die Assembly muss auch in einem anderen Ordner abgelegt werden.
Doch der Reihe nach: Das benötigte BuildCompletedEvent für VNext Builds, das als Rückgabewert von SubscribedTypes definiert werden muss, versteckt sich im Namespace Microsoft.TeamFoundation.Build.WebApi.Events der Assembly Microsoft.TeamFoundation.Build2.WebApi, welche im NuGet Paket Microsoft.TeamFoundationServer.ExtendedClient enthalten ist.
Der zweite Schritt ist das Ablegen der Plugin-Assembly, welche die Implementierung des ISubscriber Interfaces enthält, im Ordner %ProgramFiles%\Microsoft Team Foundation Server 14.0\Application Tier\TFSJobAgent\Plugins. Eine TFS Erweiterung welche sowohl XAML Build Completion Events, als auch JSON Build Completion Events verarbeiten kann, ist demnach an zwei Orte auf dem App-Tier zu verteilen.
Fazit
Eigene Erweiterungen für den TFS zu schreiben ist im Grunde einfach, Microsoft stellt eine umfangreiche API zur Verfügung, die nur benutzt werden will. Gelegentlich ist es jedoch etwas undurchsichtig, welche Klasse sich in welcher Assembly versteckt und wie diese Klasse richtig benutzt wird.