Заметки консультанта

Шамрай Александр Владимирович

Автоматизация изменений состояний рабочих элементов Azure DevOps на основе состояний дочерних элементов

Posted by Shamrai Alexander на 19 февраля, 2019

На форумах часто встречается вопросы:

  1. Есть ли какой-то сервис для автоматического изменения состояния пользовательской истории, если отрыли любую дочернюю задачу.
  2. Как можно автоматически закрыть требование, если все дочерние задачи закрыты.

На сколько верно автоматизировать эти вопросы – это тема дискуссионная, и каждый сам для себя выбирает правильный ответ. Если все-таки есть желание автоматизировать изменение состояний, то для этого существуют отдельные сервисы, например, TFS Aggregator (Web Service) или другие кастомные сервисы.

Но т.к. задачи на самом деле с точки зрения разработки не очень сложные, то содержание отдельного сервиса может быть избыточным. Иногда можно обойтись небольшими задачами на основе библиотек для взаимодействия через REST API, которые будут выполняться через стандартный планировщик задач. Такой пример мы здесь и рассмотрим.

Тут будут следующие основные шаги:

  1. Подключение к сервису. Пример есть здесь: VSTS Rest Api. 1. Подключение к сервису.
  2. Выполнения запроса по рабочим элементам, чтобы иметь список интересующих нас «родителей». Пример выполнения запроса: Azure DevOps Services Rest Api. 4. Выполнение запросов по рабочим элементам
  3. Обновить состояние «родителям», которые удовлетворяют нашим условиям. Пример обновления: Azure DevOps Services Rest Api. 3. Создание и редактирование рабочих элементов

Изменение родителя, если любой дочерний элемент изменился

Примеры тут могут быть следующие:

  1. Открывается пользовательская история, если исполнитель отрыл дочернюю задачу.
  2. Открывается фича, если любая дочерняя пользовательская история открылась.

Это простой сценарий, т.к. нам нужно сделать запрос по рабочим элементам, который отберет пользовательские истории в состоянии New и с дочерними задачами в состоянии Active. Пример запроса в формате WIQL может быть следующий:

SELECT [System.Id] FROM WorkItemLinks WHERE ([Source].[System.TeamProject] = ‘Team project name’ AND [Source].[System.WorkItemType] = ‘User story’ AND [Source].[System.State] = ‘New’) And ([System.Links.LinkType] = ‘System.LinkTypes.Hierarchy-Forward’) And ([Target].[System.WorkItemType] = ‘Task’ AND [Target].[System.State] = ‘Active’) ORDER BY [System.Id] mode(MustContain)

Нас интересуют только идентификаторы рабочих элементов верхнего, которые в результате выполнения запроса не имеют участника Source. Пример обработки результата:

static List<int> GetParentIdsFromQueryResult(string pWiql)

{

Wiql _wiql = new Wiql { Query = pWiql };

WorkItemQueryResult result = WITClient.QueryByWiqlAsync(_wiql).Result;

if (result.WorkItemRelations != null)

return (from links in result.WorkItemRelations where links.Source == null select links.Target.Id).ToList();


return new List<int>();

}

Далее все найденные идентификаторы обновляем до активного состояния. При этом функция обновления проста, т.к. нам нужно обновить только одно поле:


static void UpdateWorkItemState(int parentId, string pDestinationState)

{

JsonPatchDocument patchDocument = new JsonPatchDocument();

patchDocument.Add(new JsonPatchOperation()

{

Operation = Operation.Add,

Path = «/fields/» + StateFieldName,

Value = pDestinationState

});

WorkItem _updatedWi = WITClient.UpdateWorkItemAsync(patchDocument, parentId).Result;

Console.WriteLine(«Work Item Has Been Updated:{0} — {1}», _updatedWi.Id, _updatedWi.Fields[«System.State»].ToString());

}

Изменение родителя, если все дочерние элементы в необходимом состоянии

Тут рассматривается вариант, если необходимо закрыть пользовательскую историю, когда все дочерние задачи закрыты.

В данном случае получение необходимых родителей схож с первым вариантом. Но нам необходимо знать: все ли дочерние задачи закрыты. Это одним запросом не выполнишь. Можно использовать два варианта:

  1. Получать родителя со всеми ссылками на дочерние элементы. Потом получать дочерние задачи, анализировать их состояние и принимать необходимое решение.
  2. Также можно выполнить два запроса для каждого родителя: количество всех дочерних задач и количество закрытых дочерних задач. Если они равны, то закрываем пользовательскую историю. Рассмотрим этот вариант.

Запросы для родительских пользовательских историй:

  1. Получить родителя и закрытые дочерние задачи:

SELECT[System.Id] FROM WorkItemLinks WHERE([Source].[System.TeamProject] = ‘Team project name’ AND [Source].[System.Id] = Parent_ID) And([System.Links.LinkType] = ‘System.LinkTypes.Hierarchy-Forward’) And ([Target].[System.WorkItemType] = ‘Task’ AND [Target].[System.State] = ‘Closed’) ORDER BY [System.Id] mode(MustContain)

  1. Получить родителя и все дочерние задачи

SELECT[System.Id] FROM WorkItemLinks WHERE([Source].[System.TeamProject] = ‘Team project name’ AND [Source].[System.Id] = Parent_ID) And ([System.Links.LinkType] = ‘System.LinkTypes.Hierarchy-Forward’) And ([Target].[System.WorkItemType] = ‘Task’) ORDER BY [System.Id] mode(MustContain)

Получить количество дочерних рабочих элементов из запроса можно следующим образом:


static int GetChildsCountFromQueryResult(string pWiql)

{

Wiql _wiql = new Wiql { Query = pWiql };

WorkItemQueryResult result = WITClient.QueryByWiqlAsync(_wiql).Result;


if (result.WorkItemRelations != null)


return (from links in result.WorkItemRelations where links.Source != null select links.Target.Id).Count();


return 0;

}

Затем сравниваем количество и обновляем тем же методом, как и в первом варианте.

Решение пример

Решение можно получить и скомпилировать отсюда: https://github.com/ashamrai/AzureDevOpsExtensions/tree/master/CustomNetTasks/UpdateParentState

Перед запуском приложения необходимо:

  1. Установить правильный адрес Azure DevOps сервиса или сервера в константу ServiceUrl.
  2. Сгенерировать Personal Access Token и вставить в константу PAT.
  3. Добавить в список _projects названия командных проектов для обработки: _projects.Add(«Yor team project name»);

Один ответ to “Автоматизация изменений состояний рабочих элементов Azure DevOps на основе состояний дочерних элементов”

  1. […] Rest Api. Пример его использования приводился здесь: Автоматизация изменений состояний рабочих элементов A…. Однако использование данного метода требует наличия […]

Добавить комментарий

Заполните поля или щелкните по значку, чтобы оставить свой комментарий:

Логотип WordPress.com

Для комментария используется ваша учётная запись WordPress.com. Выход /  Изменить )

Google photo

Для комментария используется ваша учётная запись Google. Выход /  Изменить )

Фотография Twitter

Для комментария используется ваша учётная запись Twitter. Выход /  Изменить )

Фотография Facebook

Для комментария используется ваша учётная запись Facebook. Выход /  Изменить )

Connecting to %s

 
%d такие блоггеры, как: