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

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

Archive for the ‘Visual Studio’ Category

Azure DevOps Services Rest Api. 5. Создание рабочих элементов на основе шаблонов

Posted by Shamrai Alexander на Ноябрь 29, 2018

Шаблоны рабочих элементов позволяют определить какие-либо частые сценарии создания рабочих элементов с предопределенным набором значений для полей. Шаблоны позволяют сделать процесс создания новых рабочих элементов проще. Шаблоны рабочих элементов регистрируются в настройках команды:

В дальнейшем при создании новых рабочих элементов можно применять существующие шаблоны:

Эти же шаблоны можно применять при создании рабочих элементов на основе Rest Api. В этом случае будет использоваться метод CreateWorkItemAsync, который рассматривался здесь. Но перед этим необходимо получить определение хранимого шаблона рабочего элементам, чтоб понимать какие поля необходимо заполнить по умолчанию.

Для получения информации о шаблонах рабочих элементов необходимо выполнить следующее:

  • Получить информацию о проекте через клиента ProjectHttpClient.
  • Создать контекст команды TeamContext, в которой хранится шаблон рабочего элемента. В данном примере используется контекст команды по умолчанию.
  • Через контекст команды получить список всех шаблонов через метод GetTemplatesAsync, из которого уже можно получить идентификатор необходимого шаблона. Метод принимает только один параметр – контекст команды. Результат метода – список шаблонов WorkItemTemplateReference без набора полей.
  • Получить полную информацию о шаблоне и его полях через метод GetTemplateAsync. Данный метод требует использование контекста команды и идентификатора необходимого шаблона.

Пример поиска шаблона рабочего элемента:

//получить проект

var project = ProjectClient.GetProject(projectName).Result;

//создать контекст команды

TeamContext tmcntx = new TeamContext(project.Id, project.DefaultTeam.Id);

//получить все шаблоны команды

var templates = WitClient.GetTemplatesAsync(tmcntx).Result;

//получить идентификатор шаблона через его имя

var id = (from tm in templates where tm.Name == templateName select tm.Id).FirstOrDefault();

if (id != null) return WitClient.GetTemplateAsync(tmcntx, id).Result;

Полученный шаблон WorkItemTemplate включает следующие атрибуты:

  1. Id – идентификатор шаблона.
  2. Name – наименование шаблона.
  3. WorkItemTypeName – наименование типа рабочего элемента, к которому применяется шаблон.
  4. Fields – словарь с набором полей по умолчанию и их значениями.

Получив поля, уже можно создавать новый рабочий элемент:

Dictionary<string, object> fields = new Dictionary<string, object>();//поля пользователя

fields.Add(«System.Title», «New work item»);

JsonPatchDocument patchDocument = new JsonPatchDocument();

foreach (var templateKey in template.Fields.Keys) //применяем все поля из шаблона

if (!fields.ContainsKey(templateKey)) //исключаем поля, которые определяет пользователь

patchDocument.Add(new JsonPatchOperation()

{

Operation = Operation.Add,

Path = «/fields/» + templateKey,

Value = template.Fields[templateKey]

});

//добавляем поля пользователя

foreach (var key in fields.Keys)

patchDocument.Add(new JsonPatchOperation()

{

Operation = Operation.Add,

Path = «/fields/» + key,

Value = fields[key]

});

return WitClient.CreateWorkItemAsync(patchDocument, projectName, template.WorkItemTypeName).Result;

Пример тестового приложения можно посмотреть здесь:

https://github.com/ashamrai/TFRestApi/tree/master/05.TFRestApiAppCreateWorkItemFromTemplate

English version

Реклама

Posted in Microsoft, Team Foundation Server, Visual Studio, visual studio team services | Отмечено: , , , , | Leave a Comment »

Azure DevOps Services Rest Api. 4. Выполнение запросов по рабочим элементам

Posted by Shamrai Alexander на Октябрь 17, 2018

Основным клиентом для работы с запросами по рабочим элементам является WorkItemTrackingHttpClient. Используются следующие методы:

  • GetQueryAsync – информация о запросе по рабочим элементам.
  • QueryByWiqlAsync – выполнение запроса WIQL.
  • CreateQueryAsync – создание нового запроса по рабочим элементам.
  • UpdateQueryAsync – обновление существующего запроса.
  • DeleteQueryAsync – удаление существующего запроса.

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

  1. project – имя командного проекта, в котором находится запрос.
  2. query – путь к запросу, детализацию которого нужно получить.
  3. expand – уровень детализации информации о запросе.
  4. depth – количество уровней дочерних запросов и каталогов, который будет загружен в ответ метода

Пример выполнения метода:

QueryHierarchyItem detiledQuery = WitClient.GetQueryAsync(project, query.Path, QueryExpand.All, 1).Result;

Результатом является экземпляр класса detiledQuery со следующими полезными атрибутами:

  1. Name – наименование запроса
  2. Path – полный путь к запросу.
  3. IsFolder – признак, что это каталог.
  4. Wiql – Wiql текст запроса
  5. HasChildren – признак, что существуют дочерние экземпляры.
  6. Children – список дочерних экземпляров.

Для получения информации о корневых запросах (обычно это «Мои запросы» и «Общие запросы») можно использовать метод GetQueriesAsync, который имеет почти такие же параметры, как и в GetQueryAsync. Отличается только отсутствием параметра query, т.к. выполняется получение информации из корня дерева запросов.

List<QueryHierarchyItem>
rootQueries = WitClient.GetQueriesAsync(project, QueryExpand.All).Result;

Выполнить запрос можно через метод QueryByWiqlAsync со следующими параметрами:

  1. wiql – текст запроса на основе синтаксиса WIQL.
  2. project – наименование командного проекта, если используется макрос @project в теле запроса.

Пример выполнения метода:

WorkItemQueryResult result = WitClient.QueryByWiqlAsync(wiql, teamProject).Result;

Результат WorkItemQueryResult может быть обработан двумя методами:

1. Если запрос является простым списком, то получить список идентификаторов рабочих элементов можно из атрибута WorkItems. Этот атрибут включает список из WorkItemReference, который включает Id рабочего элемента и его URL.

foreach (var wiRef in result.WorkItems)

{

var wi = GetWorkItem(wiRef.Id);

Console.WriteLine(String.Format(«{0} — {1}», wi.Id, wi.Fields[«System.Title»].ToString()));

}

2. Если запрос включает ссылки, то результат можно получить из атрибута WorkItemRelations, который представляет собой список экземпляров WorkItemLink. WorkItemLink включает атрибуты:

  1. Rel – системное наименование ссылки. Наименование будет пустым, если это элемент верхнего уровня.
  2. Source – экземпляр WorkItemReference, который определяет рабочий элемент источник ссылки. Будет равным null, если это элемент верхнего уровня.
  3. Target – экземпляр WorkItemReference, который определяет рабочий элемент, на который ссылаются.

Пример использования:

foreach (var wiRel in result.WorkItemRelations)

{

if (wiRel.Source == null)

{

var wi = GetWorkItem(wiRel.Target.Id);

Console.WriteLine(String.Format(«Top Level: {0} — {1}», wi.Id, wi.Fields[«System.Title»].ToString()));

}

else

{

var wiParent = GetWorkItem(wiRel.Source.Id);

var wiChild = GetWorkItem(wiRel.Target.Id);

Console.WriteLine(String.Format(«{0} —> {1} — {2}», wiParent.Id, wiChild.Id, wiChild.Fields[«System.Title»].ToString()));

}

}

Запрос по рабочим элементам можно сконструировать с помощью синтаксиса WIQL: Syntax for the Work Item Query Language (WIQL). Однако можно пойти простым путем:

  1. В Visual Studio создать запрос и сохранить его на локальный диск:

  1. Сам текст WIQL можно просмотреть в теле запроса с помощью блокнота:

Если же необходимо выполнить запрос, который хранится на сервисе, то это можно сделать следующими шагами:

  1. Получить WIQL текст запроса через метод GetQueryAsync
  2. Выполнить запрос через метод QueryByWiqlAsync

Пример выполнения сохраненного запроса:

QueryHierarchyItem query = WitClient.GetQueryAsync(teamProject, queryPath, QueryExpand.Wiql).Result;

WorkItemQueryResult result = WitClient.QueryByWiqlAsync(query.Wiql, teamProject).Result;

Пример тестового приложения можно посмотреть здесь:

https://github.com/ashamrai/TFRestApi/blob/master/04.TFRestApiAppWorkItemQueries

English version

Posted in Microsoft, Team Foundation Server, Team Foundation Server FAQ, Visual Studio, visual studio team services | Отмечено: , , | 1 Comment »

(VSTS) Azure DevOps Services Rest Api. 3. Создание и редактирование рабочих элементов

Posted by Shamrai Alexander на Сентябрь 20, 2018

Для создания и редактирования рабочих элементов используется клиент WorkItemTrackingHttpClient с методами CreateWorkItemAsync и UpdateWorkItemAsync. Основным параметром, который используется для создания и обновления рабочих элементов, является JsonPatchDocument, который содержит информацию о полях в виде списка JsonPatchOperation.

JsonPatchOperation включает в себя следующие поля:

  • Operation – операция, выполняемая с полем:
    • Add – вставить новое значение.
    • Remove – удалить значение из поля.
    • Replace – заменить значение в поле.
    • Test – проверить значение в поле перед обновлением рабочего элемента.
  • Path – путь к полю, значение которого обновляется. Путь поля выглядит как «/fields/{Имя_поля}» или «/fields/{Ссылочное_имя_поля}»
  • Value – значение поля.

Создание выполняется через CreateWorkItemAsync с параметрами JsonPatchDocument, имя проекта и название типа рабочего элемента:

Dictionary<string, object> fields = new Dictionary<string, object>();
fields.Add(«Title», «Bug from app»);
fields.Add(«Repro Steps», «<ol><li>Run app</li><li>Crash</li></ol>»);
fields.Add(«Priority», 1);

var newBug = CreateWorkItem(«TFSAgile», «Bug», fields);

static WorkItem CreateWorkItem(string ProjectName, string WorkItemTypeName, Dictionary<string, object> Fields)
{

JsonPatchDocument patchDocument = new JsonPatchDocument();

foreach (var key in Fields.Keys)

patchDocument.Add(new JsonPatchOperation() {

Operation = Operation.Add,
Path = «/fields/» + key,
Value = Fields[key]

});

return WitClient.CreateWorkItemAsync(patchDocument, ProjectName, WorkItemTypeName).Result;

}

Обновление выполняется через UpdateWorkItemAsync с параметрами JsonPatchDocument и идентификатор рабочего элемента:

Dictionary<string, object> fields = new Dictionary<string, object>();
fields.Add(«Title», «Bug from app updated»);
fields.Add(«Repro Steps», «<ol><li>Run app</li><li>Crash</li><li>Updated step</li></ol>»);
fields.Add(«History», «Comment from app»);
var editedBug = UpdateWorkItem(WIId, fields);

static WorkItem UpdateWorkItem(int WIId, Dictionary<string, object> Fields)
{

JsonPatchDocument patchDocument = new JsonPatchDocument();

foreach (var key in Fields.Keys)

patchDocument.Add(new JsonPatchOperation()
{

Operation = Operation.Add,
Path = «/fields/» + key,
Value = Fields[key]

});

return WitClient.UpdateWorkItemAsync(patchDocument, WIId).Result;

}

Пример тестового приложения можно посмотреть здесь:

https://github.com/ashamrai/TFRestApi/tree/master/03.TFRestApiAppCreateEditWorkItems

English version

Posted in Microsoft, Team Foundation Server, Visual Studio, visual studio team services | Отмечено: , , , , | Leave a Comment »

VSTS Rest Api. 2. Получение рабочих элементов

Posted by Shamrai Alexander на Сентябрь 11, 2018

Список примеров: Microsoft Visual Studio Team Services Rest Api

Для получения доступа к рабочим элементам и их типам используется клиент WorkItemTrackingHttpClient со следующими методами:

  • Для получения одного рабочего элемента GetWorkItemAsync или нескольких GetWorkItemsAsync со следующими основными параметрами:
    • Id – идентификатор рабочего элемента, который необходимо получить. Для GetWorkItemsAsync используется список идентификаторов.
    • fields – список полей, которые необходимо получить в рабочем элементе
    • asOf – строка, которая содержит дату, которой должно соответствовать содержание рабочего элемента.
    • expand – получить расширенные свойства рабочего элемента. Возможные варианты (на практике используются обычно all и relations):
      • all – получить все свойства.
      • fields – получить только поля.
      • links – получить дополнительно справочные ссылки.
      • none – без дополнительных свойств.
      • relations – получить дополнительно информацию о связях.
  • Для типов рабочих элементов GetWorkItemTypeAsync со следующими параметрами:
    • project – имя проекта
    • type – имя типа рабочего элемента

Класс рабочего элемента можно представить в следующем виде:

public class
WorkItem

{

public int? Id { get; set; }

public int? Rev { get; set; }

public
IDictionary<string, object> Fields { get; set; }

public
IList<WorkItemRelation> Relations { get; set; }

public
ReferenceLinks Links { get; set;
}

}

Поля класса:

  • Id – идентификатор рабочего элемента.
  • Rev – номер версии рабочего элемента.
  • Fields – словарь в виде «имя поля» — «его значение». Этот список содержит только поля, которые имеют установленные значения. Если нужно знать наличие поля в типе рабочего элемента, то его можно получить через GetWorkItemTypeAsync, как указано в примере.
  • Relations – список связей рабочего элемента.
  • Links – класс с дополнительными вспомогательными ссылками на сам рабочий элемент, его тип, поля, истории и т.д.

Пример вызовов методов для получения рабочих элементов:

  • Получить один рабочий элемент:


static WorkItem GetWorkItem(int Id)

{

return WitClient.GetWorkItemAsync(Id).Result;

}

  • Получить рабочий элемент и его связи:


static WorkItem GetWorkItemWithRelations(int Id)

{

return WitClient.GetWorkItemAsync(Id, expand: WorkItemExpand.Relations).Result;

}

  • Получить тип рабочего элемента:


static WorkItemType GetWorkItemType(WorkItem WI)

{

return WitClient.GetWorkItemTypeAsync((string)WI.Fields[«System.TeamProject»], (string)WI.Fields[«System.WorkItemType»]).Result;

}

Пример приложения можно посмотреть здесь:

https://github.com/ashamrai/TFRestApi/tree/master/02.TFRestApiAppGetWorkItems

English version

Posted in Microsoft, Visual Studio, visual studio team services | Отмечено: , , , , | 1 Comment »

VSTS Rest Api. 1. Подключение к сервису

Posted by Shamrai Alexander на Август 30, 2018

Для того, чтобы взаимодействовать с VSTS или TFS, можно использовать несколько подходов:

  1. Разработать собственные библиотеки через HttpClient, что не является сложным, и пример можно посмотреть здесь.
  2. Использовать существующие nugget пакеты, чтобы упростить себе жизнь: Microsoft.TeamFoundationServer.Client.

Пример установки пакетов и результата отображен ниже.

Рисунок 1. Поиск пакета для установки

Рисунок 2. Обновленные ссылки проекта

Подключение можно выполнить через VssConnection несколькими методами:

  • Подключение к TFS с использованием текущего пользователя:

VssConnection connection = new VssConnection(new Uri(ServiceURL), new VssCredentials());

  • Подключение к TFS с указанием пользователя и его пароля:

VssConnection connection = new VssConnection(new Uri(ServiceURL), new WindowsCredential(new NetworkCredential(User, Password)));

VssConnection connection = new VssConnection(new Uri(ServiceURL), new VssBasicCredential(string.Empty, PAT));

Для дальнейшего взаимодействия необходимо создать клиентов следующим образом:

WitClient = Connection.GetClient<WorkItemTrackingHttpClient>();

BuildClient = Connection.GetClient<BuildHttpClient>();

ProjectClient = Connection.GetClient<ProjectHttpClient>();

GitClient = Connection.GetClient<GitHttpClient>();

TfvsClient = Connection.GetClient<TfvcHttpClient>();

TestManagementClient = Connection.GetClient<TestManagementHttpClient>();

Перечень основных клиентов:

  • WorkItemTrackingHttpClient – клиент для работы с рабочими элементами.
  • GitClient – клиент для работы с хранилищем исходного кода Git.
  • TfvsClient – клиент для работы с хранилищем исходного кода TFVC.
  • TestManagementClient – клиент для работы с тестовыми планами, тестами и т.д.
  • BuildClient – клиент для работы со сборками.
  • ProjectClient – клиент для работы с командными проектами.

Пример приложения можно посмотреть здесь: https://github.com/ashamrai/TFRestApi/tree/master/01.TFRestApiApp

 

English version.

Posted in Microsoft, Team Foundation Server FAQ, Visual Studio, visual studio team services, Work Item Tracking FAQ | Отмечено: , , , , | Leave a Comment »

Динамическое изменение свойств веб приложений при развертывании релизов Visual Studio Team Services

Posted by Shamrai Alexander на Июнь 29, 2018

При развертывании веб-приложений можно использовать различные Web.config или appsettings.json, чтобы применять различные строки подключении к базам, служебные логины и пароли и т.д. для различных сред, на которых веб приложение будет выполняться. Но, если хранить такие данные для среды разработки и тестовых стендов еще можно, то такие данные для промышленных сред желательно убрать от общих глаз. Одним из элементов, который позволяет упростить ситуацию с хранением учетных данных, строк подключения и т.д., является трансформация элементов конфигурации. Т.е. есть возможность динамически и прозрачно для разработчиков и поддержки устанавливать необходимые конфигурации в зависимости от среды развертывания. Данный элемент настраивается на шаге развертывания веб приложения в Azure или IIS. Пример для указания какие фалы изменять показан ниже:

А в свойствах определения релиза уже указываются: какие свойства необходимо заменить на какие значения, при этом конфиденциальные данные могут быть скрыты:

Posted in Microsoft, Team Foundation Server, Visual Studio, visual studio team services | Отмечено: , , , , | Leave a Comment »

Как установить порог качества для развертывания релиза в TFS и VSTS

Posted by Shamrai Alexander на Май 15, 2018

Возможности TFS/VSTS Release Management позволяют обеспечить «врата качества» не только на основе утверждения от какого-то участника команды разработки, когда он в ручном режиме «дает добро» на развертывание релиза на необходимом стенде, но и на основе привязки к запросам по рабочим элементам. Это позволяет обеспечить следующие правила проверки для развертывания на стенде:

  1. Не превысили ли мы порог количества высоко приоритетных или важных ошибок на релиз или продукт.
  2. Все ли требования для данного релиза покрыты тестами.
  3. Все ли тесты для релиза закрыты после проверки.
  4. И т.д.

Приведем небольшой пример: на момент выкатки релиза не должно быть ошибок с критической важностью. Для этого нужно выполнить следующие шаги:

  • Предварительно необходимо подготовить запрос по рабочим элементам, который отберет необходимые ошибки:

  • Далее перейти на страницу редактирования релиза:

  • Перейти на свойства предварительных условий для развертывания в необходимой среде:

  • Выбрать в разделе Gates пункт Query Work Items

  • Указать наименование для проверки в секции Display Name и в выпадающем списке указываем запрос, который содержит выборку необходимых рабочих элементов, в секции Query. Также в можно указать максимальный и минимальный порог для количества отбираемых рабочих элементов.

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

  • Если указанный в настройках запрос не содержит никаких рабочих элементов, то развертывание запуститься сразу. В противном случае развертывание не будет происходить и будет показана следующая подсказка:

  • При просмотре журнала развертывания можно увидеть примерно следующий результат:

  • На основе полученной информации выполняются необходимые действия. Например, можно закрыть важные ошибки, если это забыли сделать тестировщики (что вряд ли). После этого релиз развернется автоматически через определенное время, которое тоже указывается в настройках. Либо можно отклонить развертывание, а потом отклонить релиз и заняться исправлением незакрытых проблем. Пример отмены выполнения развертывания:

Posted in Microsoft, Release Management FAQ, Team Foundation Server FAQ | Отмечено: , , , , | Leave a Comment »

Динамическая обработка событий TFS/VSTS на основе скриптового выполнения С# кода и REST API

Posted by Shamrai Alexander на Март 30, 2018

Подготовка различных синхронизационных «мостиков» между системами или обработка событий для отдельной системы и выполнение в ней изменений заставляет создавать отдельные модули (веб-сервисы, исполняемые модули и т.д.). Это в свою очередь включает необходимость прохождения циклов тестирования, остановки сервисов, развертывания при их изменении в дальнейшем и т.д. Конечно можно идти через использование скриптовых языков, например, 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»&#187;), 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

Posted in Microsoft, Team Foundation Server, Visual Studio, visual studio team services | Отмечено: , , , , , , | Leave a Comment »

Использование решения на основе веб-приложения ASP .Net Core для обработки веб-хуков TFS и VSTS

Posted by Shamrai Alexander на Март 1, 2018

Данная публикация является развитием предыдущей статьи и базовые элементы берутся из нее: Создание WCF сервиса для обработки событий из Team Foundation Server или Team Services.

Если говорить о различиях создания сервиса обработки на основе ASP .Net Core и WCF, то как можно выделить следующее:

  • WCF сервис не умеет разбирать списки в приходящих json. Для того, чтобы «научить» его делать это, необходимо использовать Newtonsoft.Json и дополнительный код в классах, что незначительно повышает трудоемкость поддержки. Веб-Api на основе ASP .Net Core в свою очередь не требует никакой дополнительной доработки для разбора json в теле запроса, только лишь необходимо правильно составить класс, структуру которого можно подсмотреть при тестировании запроса:

Рисунок 1. Отображение структуры json при тестировании запроса

Таблица 1. Реализация класса для обработки json

Реализация WCF и Newtonsoft.Json Реализация ASP .Net Core
public class WorkItemEventCore
{

[JsonProperty(«subscriptionId»)]
public string subscriptionId;
[JsonProperty(«notificationId»)]
public int notificationId;
[JsonProperty(«id»)]
public string id;
[JsonProperty(«eventType»)]
public string eventType;
[JsonProperty(«publisherId»)]
public string publisherId;
[JsonProperty(«message»)]
public MessageClass message;
[JsonProperty(«detailedMessage»)]
public DetailedMessageClass detailedMessage;
[JsonProperty(«resourceVersion»)]
public string resourceVersion;
[JsonProperty(«resourceContainers»)]
public Dictionary<string, ResourceContainerClass> resourceContainers;
[JsonProperty(«createdDate»)]
public string createdDate;

}

public class WorkItemEventCore
{
public string subscriptionId;

public int notificationId;

public string id;

public string eventType;

public string publisherId;

public MessageClass message;
public DetailedMessageClass detailedMessage;

public string resourceVersion;

public Dictionary<string, ResourceContainerClass> resourceContainers;

public string createdDate;

}

  • WCF решение можно размещать и на веб-сервере, и как отдельно стоящий сервис. Веб-приложение ASP .Net Core в свою очередь может также работать через веб-сервер, как сервис, но и дополнительно решение может являться мульти платформенным.

Поэтому, исходя из возможностей и перспектив развития своего решения, выбираем необходимую платформу. В текущем случае — веб-приложение ASP .Net Core. Для создания данного решения необходимо выполнить следующие шаги:

  • Создать веб-приложение ASP.Net Core

Рисунок 2. Создание веб-приложения

  • Выбрать шаблон проекта Веб-API

Рисунок 3. Выбор решения веб-api

namespace TFSServices.Controllers

{

[Produces(«application/json»)]

[Route(«api/TS/workitems/created»)]
public class TeamServicesWICreatedController : Controller

{
// POST: api/TS/workitems/created

[HttpPost]
public void Post([FromBody]TSEvents.WorkItemEvent.WorkItemEventCreated value)

{

}

}

[Produces(«application/json»)]

[Route(«api/TS/workitems/updated»)]


public class TeamServicesWIUpdatedController : Controller

{
// POST: api/TS/workitems/updated

[HttpPost]
public void Post([FromBody]TSEvents.WorkItemEvent.WorkItemEventUpdated value)

{

}

}

}

  • Далее тестируем запрос, при этом указываем относительный адрес, который присутствует при определении контроллера ([Route(«api/TS/workitems/updated»)]), и получаем следующий результат:

Рисунок 4. Указание необходимого адреса и тестирование решение

Рисунок 5. Отладка решения

Пример решения данной статьи находится здесь: https://github.com/ashamrai/tfevents

Posted in Microsoft, Team Foundation Server, Visual Studio, visual studio team services | Отмечено: , , , | Leave a Comment »

Дополнительная настройка стандартных RDL отчетов Team Foundation Server

Posted by Shamrai Alexander на Февраль 23, 2018

Отчеты на основе SQL Server Reporting Services, которые поставляются «из коробки» в TFS, предоставляют достаточно информации для понимания ситуации с качеством и текущими требованиями в работе. Весь список отчетов можно посмотреть здесь: https://docs.microsoft.com/en-us/vsts/report/sql-reports/reporting-services-reports. Команде конечно может хватать оперативных отчетов, которые предоставляет TFS (VSTS) на основе отчетов от запросов по рабочим элементам, цифровым панелям и т.д.: https://docs.microsoft.com/en-us/vsts/report/dashboards/overview. Но, если же нет желания предоставлять доступ к проектам и исходному коду внешним пользователям, а на это может быть достаточно причин, то можно воспользоваться отчетам SQL Server Reporting Services и Power BI. В рамках данной статьи мы рассмотрим, как можно дополнительно настроить один из стандартных отчетов SQL Server Reporting Services.

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

  • Включена ли отчетность SQL Server Reporting Services. Если нет, то ее можно подключить этими шагами: https://docs.microsoft.com/en-us/vsts/report/admin/add-reports-to-a-team-project
  • Есть ли отчеты для выбранного проекта. Если нет, то можно подключить следующими шагами: https://ashamray.wordpress.com/2018/02/16/create_tfs_default_reports/
  • Выбрать отчет для дополнительной настройки. В нашем случае отчет «Обзор требований» из проекта на основе шаблона CMMI, который дает полную информацию о состоянии реализации требований и их тестирования.

Рисунок 1. Пример отчета

  • Выбрать инструмент для реализации изменений. Тут будем использовать SQL Server Report Builder.
  • Открыть отчет через выбранный инструмент:

Рисунок 2. Открытие отчета

В открывшемся отчете мы увидим несколько разделов, но нас будет интересовать только два из них – Параметры и Наборы данных. Свойства одного из параметров можно увидеть на рисунке ниже.

Рисунок 3. Настройка параметра отчета

Параметры, которые имеет смысл настраивать:

  • IncludeTasks – отображать ли дочерние задачи в отчете. По умолчанию отображаются только требования без какой-либо декомпозиции. Если необходимо отображать задачи, то в значении по умолчанию устанавливаем =1.

Рисунок 4. Включение дочерних задач

Рисунок 5. Пример работы отчета

  • DisplayOwnValues – учитывать ли в трудозатратах их значение в суммарных задачах. По умолчанию установлено, что учитываются только значения конечных задач.
  • DeliverableCategory – список типов рабочих элементов, которые считаются как поставляемые типы рабочих элементов. По молчанию это требования и пользовательские истории. Но если мы хотим видеть декомпозицию выше, то мы можем добавить функции:

Рисунок 6. Добавление функции в общую структуру работ

Рисунок 7. Пример работы отчета

Вышеприведенные настройки по сути позволяют немного расширить представляемую информацию. Ниже рассмотрим еще два примера:

  1. Включение новых задач в отчет. По умолчанию учитываются только те задачи, которые были выведены из инициирующего состояния, т.е. взяты работу и потом выполнены. Все новые задачи при работе отчета игнорируются.
  2. Добавление дополнительного поля в общую таблицу отчета. Отчет отбирает достаточное количество полей, например, идентификатор, тип рабочего элемента. Но иногда есть необходимость отобразить какое-то свое пользовательское поле.

Эти два примера реализуются уже на основе набора данных. В частности, выбранный отчет как основной набор данных использует dsOverview. Изменить набор данных можно с помощью кнопки Конструктор запросов, в котором запрос находится в текстовом виде.

Рисунок 8. Изменение запроса

Рисунок 9. Пример запроса

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

Для того, чтобы включить в запрос новые задачи, необходимо закомментировать строки, которые отбрасывают эти задачи при построении иерархии данных. Это строка 98 в запросе:

Рисунок 10. Установка комментария вместо отбрасывания предложенных задач

Далее добавим поле, которого нет в стандартном наборе полей. По умолчанию список отбираемых полей можно посмотреть в свойствах набора данных:

Рисунок 11. Поля запроса

Выполним пример на основе поля Приоритет. Для начала необходимо узнать, как поле называется в общей отчетной базе данных. Сделать это можно, создав новый набор данных и подключив источник данных TfsReportsDS:

Рисунок 12. Создание нового набора данных

В конструкторе запроса необходимо выбрать представление CurrentWorkItemView и найти необходимое поле (Microsoft_VSTS_Common_Priority). Как правило, названия колонок для полей, которые подвергаются отчетности, именуются также как свойство Reference Name с заменой точек на подчеркивания.

Рисунок 13. Поле Важность

Далее необходимо «провести» отбор данного поля через все промежуточные таблицы, которые создаются при обработке данных в отчете. Это нужно сделать в следующих строках:

  • Добавить дополнительную колонку в таблицу Rollups (строка 227)

Рисунок 14. Новая колонка для отбора приоритета

  • Добавить извлечение поля приоритета (строка 259):

Рисунок 15. Получение приоритета из представления

  • Добавить столбец при обработке собственных значений (строка 390):

Рисунок 16. Добавление приоритета для собственных значений

  • Добавить колонку при создании результирующего набора данных (строка 431):

Рисунок 17. Добавление приоритета в результирующие данные

После сохранения запроса необходимо добавить новый столбец в таблицу отчета и выбрать новое поле как отображаемое значение:

Рисунок 18. Добавление нового столбца таблицу отчета

Рисунок 19. Назначение в столбец поля приоритета

Кроме этого можно поправить форматирование, чтоб поле приоритета не выстраивалось в виде дерева.

Рисунок 20. Вызов свойства поля

Рисунок 21. Исправление отступа

Сохраняем изменения и в результате получим следующий вид:

Рисунок 22. Рабочий отчет

Posted in Microsoft, Team Foundation Server, Visual Studio | Отмечено: , , , | Leave a Comment »

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