TFS 2010 API - получение рабочих элементов из слияния - PullRequest
5 голосов
/ 26 сентября 2011

Мне нужно отправить электронное письмо по завершении сборки в TFS 2010, в котором подробно описываются рабочие элементы, связанные с регистрациями, которые были скомпилированы как часть этой сборки.Это не проблема при использовании переменной associatedChangesets, доступной в рабочем процессе сборки.

Однако в производственной ситуации мы объединяем изменения из нашей ветви разработки в ветку Release.На данный момент сборка считает, что было только одно изменение - это вышеупомянутое слияние разработки в выпуск.Очевидно, что это довольно бесполезно, так как нам нужно выяснить, какие изменения были внесены в ветку, которая была объединена, и рабочих элементов , связанных.API TFS 2010?Кажется, это довольно плохо документировано с точки зрения API.Я знаю, что вы можете расширить узел истории слияний в VS2010, но, очевидно, это нехорошо, поскольку эти данные нужно собирать программно, чтобы можно было отправлять отчет по электронной почте.

1 Ответ

7 голосов
/ 28 сентября 2011

ОК ... Я думаю, что нашел решение для этого, хотя это неуклюже и, по правде говоря, я не совсем уверен, как это работает. Но здесь идет - возможно, это укажет кому-то в правильном направлении.

var associatedWorkItems = new List<WorkItem>();

//Passed in from the build workflow (this variable is available under the 'Run On Agent' sequence as 'associatedChangesets'
IList<Changeset> associatedChangesets = context.GetValue(BuildAssociatedChangesets);

if (associatedChangesets.Count > 0)
{
    var projectCollection =
        new TfsTeamProjectCollection(new Uri("http://localhost:8080/tfs/DefaultCollection"));
    VersionControlServer versionControlServer = projectCollection.GetService<VersionControlServer>();

    foreach (var changeset in associatedChangesets)
    {
        //In order to view the individual changes, load the changeset directly from the VCS.
        Changeset localChangeset = versionControlServer.GetChangeset(changeset.ChangesetId);

        foreach (Change change in localChangeset.Changes)
        {
            //Find out what was merged in.
            ChangesetMerge[] mergedChangesets = versionControlServer.QueryMerges(
                null,
                null,
                change.Item.ServerItem,
                new ChangesetVersionSpec(localChangeset.ChangesetId),
                new ChangesetVersionSpec(localChangeset.ChangesetId),
                null,
                RecursionType.Full);

            //Extract work item information from changesets being identified as merged.
            foreach (var changesetMerge in mergedChangesets)
            {
                Changeset actualChange = versionControlServer.GetChangeset(changesetMerge.SourceVersion);

                foreach (WorkItem item in actualChange.WorkItems)
                {
                    if (!associatedWorkItems.Exists(w => w.Id == item.Id))
                    {
                        associatedWorkItems.Add(item);
                    }
                }
            }
        }
    }
}

Не спрашивайте меня, как именно QueryMerges работает, но все, что я здесь делаю, говорит: покажите, что объединено как часть набора изменений. Вы заметите, что параметры ChangesetVersionSpec одинаковы - это означает, что мы просто смотрим на слияния из этой одной ревизии.

Вы получите обратно массив ChangesetMerge объектов из QueryMerges(). В классе ChangesetMerge есть свойство, называемое SourceVersion - это ChangesetId исходного объединенного набора изменений. Как только мы получим, мы можем использовать метод VersionControlServer.GetChangeset() для загрузки отдельного набора и извлечения WorkItem. Затем он добавляется в список WorkItems, которым можно манипулировать любым удобным для вас способом (в моем случае это электронное письмо). Я также использовал проверку .Exists(), чтобы убедиться, что один и тот же WorkItem не будет записан дважды.

Обратите внимание, что даже если у вас есть коллекция associatedChangesets из рабочего процесса сборки, по какой-то причине (по крайней мере для меня) свойство Changes[] внутри associatedChangesets никогда не заполнялось (следовательно, загружая каждый отдельный набор изменений с помощью VersionControlServer.GetChangeset() метод, так как кажется, что он заполняет все необходимые поля.

Как я уже сказал, 1. это неуклюжее решение (много циклов - некоторые из которых, вероятно, не нужны), 2. я не до конца понимаю, как это работает, хотя, кажется, дает требуемые результаты - я пришел этот вывод, сделав много тестов и отладок) и, наконец, - это лучшее, что я мог придумать, основываясь на ужасной документации, предоставленной Microsoft.

Надеюсь, это кому-нибудь поможет!

...