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

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

Posts Tagged ‘visual studio team services’

Azure DevOps Services Rest Api. 10. Управление настройками команд

Posted by Shamrai Alexander на 29 декабря, 2018

<< Перейти в радел «Azure DevOps Services (TFS/VSTS) Rest Api»

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

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

TeamContext teamContext = new TeamContext(TeamProjectName);

Итерации

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

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

Для добавления итерации в команду используется метод PostTeamIterationAsync, который принимает в качестве аргументов TeamSettingsIteration и контекст команды. Для объекта TeamSettingsIteration важен только уникальный идентификатор итерации, который можно получить через метод GetClassificationNodeAsync класса WorkItemTrackingHttpClient. Пример добавления итерации:

WorkItemClassificationNode projectIt = WitClient.GetClassificationNodeAsync(TeamProjectName, TreeStructureGroup.Iterations, iterationName).Result; // get iteration from project

TeamSettingsIteration teamIt = WorkClient.PostTeamIterationAsync(new TeamSettingsIteration { Id = projectIt.Identifier }, teamContext).Result; //add iteration to a team by guid

Console.WriteLine(«Added iteration « + teamIt.Name);

Удаление итерации из настроек команды выполняется подобным методом через метод DeleteTeamIterationAsync, при этом передаются контекст команды и идентификатор итерации:

WorkItemClassificationNode projectIt = WitClient.GetClassificationNodeAsync(TeamProjectName, TreeStructureGroup.Iterations, iterationNameToRemove).Result;

WorkClient.DeleteTeamIterationAsync(teamContext, projectIt.Identifier).SyncResult(); //delete iteration from team settings by guid

Console.WriteLine(«Removed iteration « + projectIt.Name);

Просмотреть набор итераций, которые использует команда, можно через метод GetTeamIterationsAsync. Данный метод принимает в качестве параметров контекст команды и временной фрейм итерации (прошедшая, текущая и будущая). Пример выполнения метода:

TeamSettingsIteration currentiteration = (WorkClient.GetTeamIterationsAsync(teamContext, «Current»).Result).FirstOrDefault();

В результаты мы получаем объект TeamSettingsIteration, который включает:

  • Id – GUID итерации
  • Name – наименование итерации
  • Path – путь итерации
  • Attributes – дополнительные атрибуты итерации:
    • StartDate – дата начала итерации
    • FinishDate – дата окончания итерации
    • TimeFrame – фрейм итерации Past (прошедшая), Current (текущая), Future (будущая)

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

List<TeamSettingsIteration> teamIterations = WorkClient.GetTeamIterationsAsync(teamContext).Result; //get all iterations

Console.WriteLine(«Team Iterations: «);

foreach (TeamSettingsIteration teamIteration in teamIterations)

Console.WriteLine(«{0} : {1} : {2}-{3}», teamIteration.Attributes.TimeFrame, teamIteration.Name, teamIteration.Attributes.StartDate, teamIteration.Attributes.FinishDate);

Области

Области имеет смысл автоматически обновлять, если основное управление ответственностями команд выполняется во внешней системе, например, через CMDB и их необходимо переносить в соответствующие команды Azure DevOps.

Как и с итерациями область должна быть сначала добавлена в настройки командного проекта (Управление областями и итерациями в командном проекте). Но оперирование областями в настройках команды отличается от управления итерациями.

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

  • DefaultValue – строковое значение области по умолчанию.
  • Values – список областей TeamFieldValue, которые будет контролировать команда. TeamFieldValue включает наименование области Value и признак включения в контроль дочерних областей IncludeChildren.

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

TeamFieldValues teamAreas = WorkClient.GetTeamFieldValuesAsync(teamContext).Result; //Get All Areas

Console.WriteLine(«Default Area: « + teamAreas.DefaultValue);

Console.WriteLine(«Team Areas : «);

foreach (TeamFieldValue teamField in teamAreas.Values)

Console.WriteLine(«\t» + teamField.Value + ((teamField.IncludeChildren)? » (include sub-areas)» : «»));

Обновление набора областей команды выполняется через один метод UpdateTeamFieldValuesAsync с параметром TeamFieldValuesPatch. TeamFieldValuesPatch включает те же атрибуты, что и TeamFieldValues. Т.е. для обновления настройки можно взять текущие значения и добавить или удалить необходимые:

string[] areas = { @»Application\WinClient», @»Application\WebClient» };

TeamFieldValues currentTeamAreas = WorkClient.GetTeamFieldValuesAsync(teamContext).Result; // get current areas

TeamFieldValuesPatch teamAreasPatch = new TeamFieldValuesPatch();

List<TeamFieldValue> newTeamAreas = new List<TeamFieldValue>(currentTeamAreas.Values); // just copy old areas. Here we may remove unneeded areas

foreach (string area in areas)

newTeamAreas.Add(new TeamFieldValue { Value = TeamProjectName + «\\» + area, IncludeChildren = false }); // add new areas

teamAreasPatch.DefaultValue = currentTeamAreas.DefaultValue;

teamAreasPatch.Values = newTeamAreas;

TeamFieldValues updatedTeamAreas = WorkClient.UpdateTeamFieldValuesAsync(teamAreasPatch, teamContext).Result;

Общие настройки

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

Получить текущие настройки можно через метод GetTeamSettingsAsync, который возвращает TeamSetting с атрибутами:

  • DefaultIteration – итерация, которая автоматически подставляется при создании нового рабочего элемента в контексте команды.
  • BacklogIteration – в рамках какой итерации отображаются рабочие элементы журнала требований.
  • DefaultIterationMacro – подстановка для определения текущей итерации: https://docs.microsoft.com/ru-ru/azure/devops/boards/queries/query-by-date-or-current-iteration?view=vsts#query-for-items-based-on-belonging-to-a-teams-current-iteration
  • BacklogVisibilities – список всех журналов, которые используются в проекте, и их отображение в команде.
  • WorkingDays – список дней, которые учитываются как рабочие для команды.

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

TeamContext teamContext = new TeamContext(TeamProjectName, TeamName);

TeamSetting teamSetting = WorkClient.GetTeamSettingsAsync(teamContext).Result;

Console.WriteLine(«Settings for the team « + TeamName);

Console.WriteLine(«Backlog Iteration : « + teamSetting.BacklogIteration.Name);

Console.WriteLine(«Default Iteration : « + teamSetting.DefaultIteration.Name);

Console.WriteLine(«Macro of Iteration : « + teamSetting.DefaultIterationMacro);

Console.WriteLine(«Categories of backlog:»);

foreach(string bkey in teamSetting.BacklogVisibilities.Keys)


if (teamSetting.BacklogVisibilities[bkey]) Console.WriteLine(«\t» + bkey);

Console.WriteLine(«Working days :»);

foreach (var wday in teamSetting.WorkingDays) Console.WriteLine(«\t» + wday.ToString());

switch (teamSetting.BugsBehavior)

{

case BugsBehavior.AsRequirements:

Console.WriteLine(«Bugs Behavior: Bugs in a requirements backlog.»);

break;

case BugsBehavior.AsTasks:

Console.WriteLine(«Bugs Behavior: Bugs in a sprint backlog as tasks.»);

break;

case BugsBehavior.Off:

Console.WriteLine(«Bugs Behavior: Find bugs through queries.»);

break;

}

Обновление настроек выполняется через метод UpdateTeamSettingsAsync с параметром TeamSettingsPatch, который имеет те же атрибуты, как и TeamSetting. При этом будут обновляться только те настройки, атрибуты которых были проинициализированы. Обновление видимых команде журналов можно выполнить следующим образом:

TeamSetting teamSetting = WorkClient.GetTeamSettingsAsync(teamContext).Result;

TeamSettingsPatch teamSettingsPatch = new TeamSettingsPatch();

teamSettingsPatch.BacklogVisibilities = teamSetting.BacklogVisibilities;

if (teamSettingsPatch.BacklogVisibilities.ContainsKey(«Microsoft.EpicCategory») && teamSettingsPatch.BacklogVisibilities[«Microsoft.EpicCategory»])

teamSettingsPatch.BacklogVisibilities[«Microsoft.EpicCategory»] = false;

if (teamSettingsPatch.BacklogVisibilities.ContainsKey(«Microsoft.FeatureCategory») && teamSettingsPatch.BacklogVisibilities[«Microsoft.FeatureCategory»])

teamSettingsPatch.BacklogVisibilities[«Microsoft.FeatureCategory»] = false;

teamSetting = WorkClient.UpdateTeamSettingsAsync(teamSettingsPatch, teamContext).Result;

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

https://github.com/ashamrai/TFRestApi/tree/master/10.TFRestApiAppManageTeamSettings

English version

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

Azure DevOps Services Rest Api. 9. Управление командами проекта

Posted by Shamrai Alexander на 27 декабря, 2018

<< Перейти в радел «Azure DevOps Services (TFS/VSTS) Rest Api»

Управление командами выполняется довольно просто через TeamHttpClient. Для управления командами достаточно знать название команды и имя проекта, в котором она находится или будет находится. Классом, который содержит информацию о команде, является класс WebApiTeam со следующими основными свойствами:

  • Id – идентификатор.
  • Name – наименование команды.
  • Description – описание команды.
  • ProjectName – наименование проекта, в которую входит команда.
  • ProjectId – идентификатор проекта, в которую входит команда.

Для получения информации о команде используется метод GetTeamAsync, который использует только два параметра имя проекта и имя команды или их идентификаторы. Получить список всех команд можно через GetTeamsAsync, указав на вход только наименование проекта:

List<WebApiTeam> teams = TeamClient.GetTeamsAsync(TeamProjectName).Result;

Console.WriteLine(«Project Teams:»);

foreach (WebApiTeam team in teams) Console.WriteLine(team.Name);

Если необходимо получить информацию об участниках команды, то можно выполнить метод GetTeamMembersWithExtendedPropertiesAsync, в который передаются все те же имя проекта и имя команды. Участник команды описывается классом TeamMember, который содержит два свойства:

  • IsTeamAdmin – является ли участник команды администратором.
  • Identity – информация об учетной записи пользователя.

Пример изучения состава команды:

List<TeamMember> teamMembers = TeamClient.GetTeamMembersWithExtendedPropertiesAsync(TeamProjectName, TeamName).Result;

string teamAdminName = (from tm in teamMembers where tm.IsTeamAdmin == true
select tm.Identity.DisplayName).FirstOrDefault();

if (teamAdminName != null) Console.WriteLine(«Team Administrator:» + teamAdminName);

Console.WriteLine(«Team members:»);

foreach (TeamMember teamMember in teamMembers)

if (!teamMember.IsTeamAdmin) Console.WriteLine(teamMember.Identity.DisplayName);

 

Для создания и обновления команды используются методы CreateTeamAsync и UpdateTeam соответственно. Основные параметры это:

  • team – объект WebApiTeam, в котором устанавливаются наименование и описание команды.
  • projectId – наименование проекта команды
  • teamId – идентификатор существующей команды, который используется только при обновлении наименования или описания.

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

WebApiTeam team = TeamClient.GetTeamAsync(TeamProjectName, TeamName).Result;

WebApiTeam updatedTeam = new WebApiTeam {

Name = team.Name + » updated»,

Description = team.Description.Replace(«Created», «Updated»)

};

updatedTeam = TeamClient.UpdateTeamAsync(updatedTeam, team.ProjectName, team.Name).Result;

Console.WriteLine(«The team ‘{0}’ has been updated in the team project ‘{1}'», updatedTeam.Name, updatedTeam.ProjectName);

 

Для удаления команды используется метод DeleteTeamAsync с наименованием проекта и удаляемой команды:

TeamClient.DeleteTeamAsync(TeamProjectName, TeamName).SyncResult();

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

https://github.com/ashamrai/TFRestApi/tree/master/09.TFRestApiAppManageTeams

English version

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

Azure DevOps Services Rest Api. 8. Управление областями и итерациями в командном проекте

Posted by Shamrai Alexander на 26 декабря, 2018

<< Перейти в радел «Azure DevOps Services (TFS/VSTS) Rest Api»

Управление областями и итерациями выполняется через WorkItemTrackingHttpClient одинаковыми методами, отличаются только некоторые моменты. Общим классом, который описывает области и итерации, является класс WorkItemClassificationNode. Он включает следующие основные свойства:

  • Id – идентификатор области или итерации.
  • Name – наименование области или итерации.
  • StructureType – тип объекта: «TreeNodeStructureType.Area» и «TreeNodeStructureType.Iteration».
  • Attributes – содержит дату начала и окончания итерации, которые доступны через ключи startDate и finishDate.

Создание области и итерации выполняется через метод CreateOrUpdateClassificationNodeAsync, который включает в себя следующие параметры:

  • postedNode – объект WorkItemClassificationNode, который содержит наименование и атрибуты.
  • project – имя командного проекта, в котором будет создана область или итерация.
  • structureGroup – тип объекта: TreeStructureGroup.Areas или TreeStructureGroup.Iterations
  • path – путь к родительской области или итерации, если она необходима.

Пример для создания области. Для создания области важно только наименование и родительская область. Если родительская область не указана, то новая область будет размещена в корне командного проекта

WorkItemClassificationNode newArea = new WorkItemClassificationNode();

newArea.Name = AreaName;

WorkItemClassificationNode result = WitClient.CreateOrUpdateClassificationNodeAsync(newArea, TeamProjectName, TreeStructureGroup.Areas, ParentAreaPath).Result;

 

Пример для создания итерации. Итерация создается также, как и область, но кроме этого можно использовать дополнительные необязательные атрибуты startDate и finishDate.

WorkItemClassificationNode newIteration = new WorkItemClassificationNode();

newIteration.Name = IterationName;

newIteration.Attributes = new Dictionary<string, object>();

newIteration.Attributes.Add(«startDate», StartDate);

newIteration.Attributes.Add(«finishDate», FinishDate);

WorkItemClassificationNode result = WitClient.CreateOrUpdateClassificationNodeAsync(newIteration, TeamProjectName, TreeStructureGroup.Iterations, ParentIterationPath).Result;

 

Обновление области и итерации выполняется через UpdateClassificationNode с теми же параметрами, как и в CreateOrUpdateClassificationNodeAsync. При этом нужно обращать внимание на параметр path. Он будет обязательным для области или итерации, если она имеет родителя. Если для такой области или итерации не указать path, то она будет перемещена в корень командного проекта. Т.е. если нам нужно переименовать или изменить даты, то необходимо снова указать необходимый путь, в котором будет находится область или итерация.

Удаление области или итерации выполняется через DeleteClassificationNodeAsync с параметрами:

  • project – имя командного проекта, в котором находится область или итерация.
  • structureGroup – тип объекта: TreeStructureGroup.Areas или TreeStructureGroup.Iterations
  • path – путь удаляемой области или итерации.
  • reclassifyId – идентификатор новой области или итерации, в которую будут перемещены рабочие элементы, которые находятся в удаляемой области или итерации.

Пример удаления.

WorkItemClassificationNode newNode = WitClient.GetClassificationNodeAsync(

TeamProjectName,

treeStructureGroup,

NewNodePath, 4).Result;

WitClient.DeleteClassificationNodeAsync(TeamProjectName, treeStructureGroup, NodePath, newNode.Id).SyncResult();

 

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

https://github.com/ashamrai/TFRestApi/tree/master/08.TFRestApiAppAreasAndIterations

English version

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

Azure DevOps Services Rest Api. 7. Добавление и редактирование связей между рабочими элементами

Posted by Shamrai Alexander на 21 декабря, 2018

<< Перейти в радел «Azure DevOps Services (TFS/VSTS) Rest Api»

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

patchDocument.Add(new JsonPatchOperation()

{

Operation = Operation.Add,

Path = «/relations/-«,

Value = new {

rel = RelName,

url = RelUrl,

attributes = new

{

comment = Comment,

isLocked = IsLocked // you must be an administrator to lock a link

}

}

});

Указываются следующие атрибуты:

  • Operation – операция со ссылкой, в основном Add и Remove для добавления и удаления.
  • Path – может иметь следующие значения:
    • «/relations/-» – добавляется новая связь между рабочими элементами
    • «/relations/[индекс ссылки]» – для редактирования свойств или удаление ссылки, где [индекс ссылки] – порядковый номер ссылки в списке WorkItem.Relations.
  • Value – детализация информации о ссылке, которая содержит:
    • rel – наименование типа ссылки, перечень можно посмотреть здесь: Link type reference.
    • url – прямой url адрес к необходимому рабочему элементу.
    • attributes – дополнительные необязательные атрибуты ссылки:
      • comment – комментарий для ссылки.
      • isLocked – блокировка ссылки. Если ссылка заблокирована, то ее можно удалить только через API.

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

JsonPatchDocument patchDocument = new JsonPatchDocument();

patchDocument.Add(new JsonPatchOperation()

{

Operation = Operation.Add,

Path = «/relations/-«,

Value = new {

rel = «System.LinkTypes.Related»,

url = RelUrl,

attributes = new

{

comment = «Comment for the link»

}

}

});

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

Обновление выполняется по следующему примеру:

JsonPatchDocument patchDocument = new JsonPatchDocument();

patchDocument.Add(new JsonPatchOperation()

{

Operation = Operation.Add,

Path = «/relations/0»,

Value = new {

rel = «System.LinkTypes.Related»,

url = RelUrl,

attributes = new

{

comment = «New comment for the link»

}

}

});

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

Удаление выполняется по следующему шаблону:

JsonPatchDocument patchDocument = new JsonPatchDocument();

patchDocument.Add(new JsonPatchOperation()

{

Operation = Operation.Remove,

Path = «/relations/0»

});

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

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

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

https://github.com/ashamrai/TFRestApi/tree/master/07.TFRestApiAppWorkItemLinks

English version

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

Azure DevOps Services Rest Api. 6. Загрузка и получение вложений для рабочих элементов

Posted by Shamrai Alexander на 14 декабря, 2018

<< Перейти в радел «Azure DevOps Services (TFS/VSTS) Rest Api»

При автоматизации некоторых процессов полезно использовать вложения рабочих элементов, которые могут включать в себя журнал работы приложения, скриншот и т.д. Для управления вложениями используются методы CreateAttachmentAsync и GetAttachmentContentAsync для загрузки и получения.

Пример для загрузки вложения включает шаги:

  1. Создание потока для чтения содержимого файла.
  2. Создание вложения на сервисе через метод CreateAttachmentAsync, который включает параметры поток и наименование вложения. Можно использовать создание вложения без файлового потока, а только с наименованием файла. Но этот подход нужно использовать, если файл для вложения находится в локальном каталоге. Иначе имя файла во вложении будет содержать путь к файлу, а не просто его наименование.
  3. Обновление рабочего элемента. Формируется JsonPatchDocument, который добавляет новую связь для рабочего элемента с типом AttachedFile. Также передается URL вложения, который будет получен на шаге 2.

AttachmentReference att;

using (FileStream attStream = new FileStream(FilePath, FileMode.Open, FileAccess.Read))

att = WitClient.CreateAttachmentAsync(attStream, filePathSplit[filePathSplit.Length — 1]).Result; // upload the file

JsonPatchDocument patchDocument = new JsonPatchDocument();

patchDocument.Add(new JsonPatchOperation()

{

Operation = Operation.Add,

Path = «/relations/-«,

Value = new

{

rel = «AttachedFile»,

url = att.Url,

attributes = new { comment = «Comments for the file « + filePathSplit[filePathSplit.Length — 1] }

}

});

WitClient.UpdateWorkItemAsync(patchDocument, WIId).Result;

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

  1. Получить рабочий элемент и его ссылки. Что получить ссылки, в метод GetWorkItemAsync передается параметр expand: WorkItemExpand.Relations.
  2. Ссылки, которые имеют вложения, имеют тип AttachedFile в свойстве Rel класса WorkItemRelation. Если нам нужен конкретный файл, то его наименование можно найти через атрибут name.
  3. Для того, чтобы получить вложение, нам необходимо получить его идентификатор. Идентификатор можно выделить из URL вложения.
  4. Далее выполняется получение потока через метод GetAttachmentContentAsync и сохранение его в необходимом файле.

WorkItem workItem = WitClient.GetWorkItemAsync(WIId, expand: WorkItemExpand.Relations).Result;

foreach(var rf in workItem.Relations)

{


if (rf.Rel == «AttachedFile»)

{


string[] urlSplit = rf.Url.ToString().Split(new
char[] { ‘/’ }, StringSplitOptions.RemoveEmptyEntries);


using (Stream attStream = WitClient.GetAttachmentContentAsync(new Guid(urlSplit[urlSplit.Length — 1])).Result) // get an attachment stream


using (FileStream destFile = new FileStream(DestFolder + «\\» + rf.Attributes[«name»], FileMode.Create, FileAccess.Write)) // create new file

attStream.CopyTo(destFile); //copy content to the file

}

}

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

https://github.com/ashamrai/TFRestApi/tree/master/06.TFRestApiAppWorkItemAttachments

English version

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

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

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

<< Перейти в радел «Azure DevOps Services (TFS/VSTS) Rest Api»

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

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

Эти же шаблоны можно применять при создании рабочих элементов на основе 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 »

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

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

<< Перейти в радел «Azure DevOps Services (TFS/VSTS) Rest Api»

Для создания и редактирования рабочих элементов используется клиент 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 | Отмечено: , , , , | 1 Comment »

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

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

<< Перейти в радел «Azure DevOps Services (TFS/VSTS) 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

<< Перейти в радел «Azure DevOps Services (TFS/VSTS) Rest Api»

Для того, чтобы взаимодействовать с 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 »

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