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

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

Динамическая обработка событий 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 »

Как создать отчеты по умолчанию в Reporting Services для проекта Team Foundation Server

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

<< Перейти в раздел «Team Foundation Server Admin FAQ»

По умолчанию, когда проект создается в TFS из веб-интерфейса, отчеты на основе Reporting Services не создаются. Однако отчеты дают неплохие возможности для подключения внешних заинтересованных лиц, включая возможность экспорта отчетов и подписки на отчеты, без необходимости обеспечения непосредственного доступа к проектам. Для того, чтобы «вернуть» набор отчетов по умолчанию, необходимо воспользоваться командой TfsConfig addProjectReports с параметрами:

/collection:’url к колекции проектов’

/teamProject:’имя проекат’

/template:’Шаблон для отчетов: CMMI, Agile или Scrum’

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

Детальная информация о команде: AddProjectReports

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

Создание WCF сервиса для обработки событий из Team Foundation Server или Team Services

Posted by Shamrai Alexander на Январь 24, 2018

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

Данная функция очень полезна, если необходимо добавить дополнительною автоматизацию, которую TFS/VSTS не поддерживают. Например, создание пула дочерних задач, при переводе рабочего элемента в определенное состояние, или установка критической даты рассмотрения дефекта в зависимости от его важности и т.д.

В этой статье мы рассмотрим возможность создания wcf сервиса, который будет в состоянии «слушать» сообщения, которые приходят из TFS или VSTS.

Пример, как создать wcf сервис, который способен принимать входящие сообщения через метод POST, можно посмотреть здесь: https://www.codeproject.com/Articles/275279/Developing-WCF-Restful-Services-with-GET-and-POST.

Основные моменты, которые стоит отметить при создании сервиса:

  • В файле определения сервиса «имя_сервиса.svc» добавить атрибут:

Factory=»System.ServiceModel.Activation.WebServiceHostFactory»

  • Для метода, который будет в дальнейшем использовать для приема сообщений от TFS/VSTS указать атрибуты, которые будут укажут, что метод POST и работать он будет в json формате.

[OperationContract]

[WebInvoke(Method = «POST», RequestFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Bare)]

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

void WorkItemChangedEvent(Stream EventData);

Для конвертирования некоторой базовой информации можно использовать следующий пример класса:

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(«resourceVersion«)]

public string resourceVersion;

[JsonProperty(«createdDate«)]

public string createdDate;

}

Данный класс используется в методе при десериализации строки в экземпляр с помощью библиотек Newtonsoft.Json:

StreamReader _reader = new StreamReader(pEventData, Encoding.UTF8);

string _eventStr = _reader.ReadToEnd();

WorkItemEventCore _wieventcorre = JsonConvert.DeserializeObject<WorkItemEventCore>(_eventStr);

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

Указывается адрес, на который отсылать сообщения, включая сервис и метод:

И после нажатия кнопки Test, можно получить информацию об успешности исполнения и пример отправленной нотификации:

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

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

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

Как синхронизировать GIT репозитории между TFS, VSTS и GitHUB

Posted by Shamrai Alexander на Январь 17, 2018

<< Перейти в раздел «Team Foundation Version Control FAQ»

Интересная статья по синхронизации TFS 2015, VSTS и GitHub через сервис сборки: https://blogs.microsoft.co.il/leonj/2017/01/24/synchronizing-tfs-2015-and-vsts-with-github/

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

Salma for Word v2.0.4

Posted by Shamrai Alexander на Декабрь 21, 2017

Выпустил очередное обновление для  Salma for Word: https://github.com/ashamrai/Salma/releases/tag/v2.0.4

Что нового:

1. Отказ от использования TFS Object Model в сторону Microsoft Team Foundation Server Extended Client. Это позволило обеспечить простую поддержку Visual Studio Team Services.

2. Добавлена функция для «устаревания» рабочих элементов. Очень часто возникает вопрос: что делать, если требование устарело? С точки зрения TFS/VSTS можно выполнить следующие шаги:

  • Просто перевести требование из закрытого состояния в активное. Но это в свою очередь «подтягивает» все ссылки, которые есть в требовании, допустим, уже закрытые работы, что будет потом отображаться в планах.
  • Можно выполнить копирование требования стандартными функциями, но в этом случае, если была декомпозиция требования на дочерние, связи не будут перенесены. А также необходимо как-то пометить требование источник, что оно уже не актуально.

Поэтому из инструмента можно выполнить:

  • Копирование требования со всем содержимым в новое требование.
  • Перенести или скопировать необходимые ссылки в новое требование.
  • Пометить старое требование в его наименовании и/или с помощью тега.
  • Сохранить ссылку на требование источник.

obs_req

3. Автоматически связывать требование и документ. Если документ, находится в сетевом доступе, то можно выполнить настройку, чтоб при создании нового требования, автоматически вставлял ссылка на документ, в котором это требование «родилось». Соответственно, из требования всегда можно открыть документ-источник и просмотреть его контекст.

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

Вебинар «Организация конвейера по производству ПО на основе VSTS» — Видео

Posted by Shamrai Alexander на Декабрь 13, 2017

Видео

Презентация

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

Быстрое создание проектов VSTS с подготовленной инфраструктурой в Azure

Posted by Shamrai Alexander на Ноябрь 15, 2017

Подготовка инфраструктуры для каждого нового проекта разработки ПО зачастую включает в себя рутинные и типовые шаги, которые можно выделить в определенную последовательность и автоматизировать. По этому пути и пошли разработчики Microsoft, и создали мастер создания проектов DevOps. Т.е. если мы имеем подписку в Azure, то каждый новый проект уже может в себя первичную инфраструктуру в виде проекта в VSTS, настроенной сборки непрерывной интеграции, непрерывного развертывания и т.д. Шаги как это можно сделать:

1. Найти в Azure необходимый сервис, который пока в режиме предварительной работы:

2. Выбрать создание нового проекта

3. Далее выбираем базу, на основе которой будет создано приложение.

4. Выбрать тип необходимого решения

5. Выбрать платформу, на основе которой будет в дальнейшем выполняться развертывание нашего решения:

6. Ну и на заключительном шаге мы указываем необходимые данные об учетной записи и записи VSTS, а также где разворачивать ресурсы и название проекта.

Что мы в результате получаем?

1. Сразу после окончания мастера нам открывается некая цифровая панель DevOps проекта, которая содержит сводную информацию и быстрые ссылки.

2. В учетной записи VSTS появляется новый командные проект с первым приложением, которое по необходимости мы можем развивать или удалить и создать новое.

3. Также появляется сборка с настроенной непрерывной интеграцией:

4. Дополнительно создается определение релиза, которое уже связанно со сборкой для обеспечения непрерывного развертывания.

5. Также данное определение релиза имеет предварительно указанные и готовые шаги (шаг) для развертывания решения в необходимой среде:

6. При этом сразу выполняется первый прогон всей цепочки – комит, сборка и развертывание.

7. Само же решение мы также можем найти в своей подписке Azure.

8. Ну а также уже присутствует интеграция с Application Insights, которое позволяет нам отслеживать, как работает наше решение, какие запросы оно делает, какие «летят» исключения и тд.

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

Ссылки на рабочие элементы в Wiki

Posted by Shamrai Alexander на Октябрь 3, 2017

Октябрьское обновление для vsts содержит новую интересную возможность для страниц Wiki, которая позволяет ссылаться на конкретные рабочие элементы в проекте. Т.е. это позволяет быстро формировать заметки к выпускаемым релизам со списком попавших в него новых возможностей и исправлений, можно также использовать в обзоре итерации, а также любых других документах, например, онлайн руководствах, для того, чтобы было понятно почему они изменились (добавилась или была удалена какая-то возможность на основе запроса от заинтересованного лица). Использовать такую возможность просто, нужно ввести символ # и добавить идентификатор рабочего элемента. При этом появляется список, который позволяет выбрать необходимый рабочий элемент:

Результирующий вид будет примерно следующим:

При этом вставленные элементы являются кликабельными, чтобы можно было посмотреть детали интересующего рабочего элемента. Конечно, было б еще полезным добавить возможность указать поле, которое я хочу видеть в wiki. Это позволило б сформировать какую-то спецификацию требований, например, в виде списка или таблицы названий требования и их текста. Но будем надеяться, что это появится в будущем.

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

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

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