Подготовка различных синхронизационных «мостиков» между системами или обработка событий для отдельной системы и выполнение в ней изменений заставляет создавать отдельные модули (веб-сервисы, исполняемые модули и т.д.). Это в свою очередь включает необходимость прохождения циклов тестирования, остановки сервисов, развертывания при их изменении в дальнейшем и т.д. Конечно можно идти через использование скриптовых языков, например, Perl для IBM Rational или PowerShell для TFS/VSTS для выполнения каких-либо действий. Но в данном случае необходимо расширять свои знания на необходимые области, что требует дополнительных усилий и времени. Поэтому можно также воспользоваться возможностью написать скрипт на основе языка, который используется для создания интеграционного механизма. Например, можно рассмотреть .Net C#. Для данного языка существует nugget пакет, который позволяет запускать код .Net C# в виде скриптов, которые можно формировать динамически. При этом можно использовать не только стандартные (системные) наборы библиотек, а также можно подключать собственные или внешние библиотеки.
Рассмотрим использование такой возможности на примере обработки событий в TFS (примеры перехвата таких событий можно посмотреть здесь и здесь). Задача для примера будет простая: записать в комментарий при изменение рабочего элемента типа «Bug», что событие было перехвачено. Пошаговая инструкция:
- Для решения необходимо применить пакет для выполнения C# скриптов Scripting API Samples.
- Также необходим пакет для взаимодействия с TFS/VSTS (в этом случае через REST API) Microsoft.TeamFoundationServer.Client.
-
Далее необходимо подготовить скрипт, который будет проверять: событие, которое пришло, удовлетворяет ли нашим критериям. Пример скрипта:
«bool CheckConditionUpdated(WorkItemEvent.WorkItemEventUpdated InputWorkItem)
{
if (InputWorkItem == null) return false;
if (InputWorkItem.resource.fields.ContainsKey(«»System.History»») && InputWorkItem.resource.fields[«»System.History»»].newValue == «»Changes from script»») return false;
if (InputWorkItem.resource.revision.fields[«»System.WorkItemType»»] == «»Bug»») return true;
return false;
}
CheckConditionUpdated(InputWorkItem)»;
Смысл простой: проверяем переданный параметр с событием на наличие информации; проверяем, что событие, которые пришло, не является следствием изменения рабочего элемента самим сервисом; проверяем, что тип рабочего элемента – Bug. Скрипт возвращает true или false.
Также необходимо подключить библиотеку и пространства имен, которые содержат описание классов с событиями:
var ScrOpt = ScriptOptions.Default.AddReferences(
Assembly.GetAssembly(typeof(WorkItemEvent.WorkItemEventUpdated))
).AddImports(«System», «TFTypesLib»);
Пример запуска скрипта с передачей параметров:
_result = CSharpScript.RunAsync<bool>(_src, ScrOpt, new ScriptWiUpdatedHost { InputWorkItem = pInputWorkItem }).Result.ReturnValue;
-
Далее формируем скрипт для обработки события:
«bool ProcessEvent(WorkItemEvent.WorkItemEventUpdated InputWorkItem)
{
if (InputWorkItem == null) return false;
JsonPatchDocument PatchDocument = new JsonPatchDocument();
PatchDocument.Add(
new JsonPatchOperation()
{
Operation = Operation.Add,
Path = «»/fields/System.History»»,
Value = «»Changes from script»»
}
);
VssCredentials Cred = new VssCredentials(true);
WorkItemTrackingHttpClient WIClient = new WorkItemTrackingHttpClient(new Uri(«»http://tfs-srv:8080/tfs/DefaultCollection»»), Cred);
WorkItem result = WIClient.UpdateWorkItemAsync(PatchDocument, InputWorkItem.resource.revision.id).Result;
return true;
}
ProcessEvent(InputWorkItem);»
Данный скрипт создает объект класса JsonPatchDocument для добавления комментария к рабочему элементу, выполняет подключение к серверу с учетными данными по умолчанию и выполняет обновление рабочего элемента. Выполнение скрипта выполняется подобно предыдущему, но с добавлением дополнительных библиотек и пространств:
var ScrOpt = ScriptOptions.Default.AddReferences(
Assembly.GetAssembly(typeof(WorkItemTrackingHttpClient)),
Assembly.GetAssembly(typeof(JsonPatchDocument)),
Assembly.GetAssembly(typeof(VssCredentials)),
Assembly.GetAssembly(typeof(WorkItemEvent.WorkItemEventUpdated)),
Assembly.GetAssembly(typeof(Uri))
).AddImports(
«Microsoft.TeamFoundation.WorkItemTracking.WebApi»,
«Microsoft.TeamFoundation.WorkItemTracking.WebApi.Models»,
«Microsoft.VisualStudio.Services.WebApi.Patch.Json»,
«Microsoft.VisualStudio.Services.WebApi.Patch»,
«Microsoft.VisualStudio.Services.Common»,
«System»,
«TFTypesLib»
);
Пример результат выполнения скрипта в журнале рабочего элемента:
Полный пример можно посмотреть здесь: https://github.com/ashamrai/tfevents/tree/master/TFSServicesMVCRoslyn