TFS2010 - В SourceGetVersion появилось неправильное изменение - PullRequest
20 голосов
/ 30 ноября 2011

Я сейчас настраиваю Team Foundation Server 2010 и обнаружил очень странное поведение при выполнении сборки:

Ситуация объяснена: У нас есть 2 филиала

  • Разработка
  • Главная

Все разработчики регистрируют код только в ветке разработки. Один раз в день менеджер сборки объединяет некоторые наборы изменений с основной веткой. В разделе «Разработка» выполняется непрерывная сборка при каждой регистрации. На главной ветке один раз в день (ночью) запускается сборка.

Теперь предположим, что наборы изменений 1-100 объединяются в основной раздел в 17:00, давая набор изменений 101 в качестве операции объединения. Некоторые разработчики проверяют наборы изменений 102-106 после 5 часов в ветке разработки. Теперь в 23:00 ежедневная сборка автоматически запускается и запускается в основной ветке. Последним набором изменений основной ветви является набор изменений 101. Однако в деталях сборки отображается набор изменений 106:

enter image description here

Я мог бы предположить, что это поведение предназначено, потому что, если вы проверяете набор изменений 106 в основной ветви, вы фактически получите содержимое набора изменений 101. Но это было бы намного более читабельным, если бы эта сводка сборки показывала правильное число .

Вопрос 1: Есть ли способ манипулирования выводом информации SourceGetVersion? Может быть через шаблон процесса сборки?

Второй сценарий, в котором TFS ведет себя странно, еще хуже: В очереди новой сборки есть возможность ввода параметра «Получить версию», как показано на следующем рисунке:

enter image description here

Если я сейчас нажму на «очередь», сборка будет запущена, и СНЯТЬ детали сборки выводит набор изменений 106, хотя я специально установил его для получения набора изменений 76.

Вопрос 2: это ошибка? Есть исправление или что-то, чтобы это исправить? Или есть какой-либо флаг, который нужно установить?

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

Спасибо за любую помощь !! Christian

РЕДАКТИРОВАТЬ 1

Структура папок командного проекта:

$ ProjectName

  • BuildProcessTemplates
  • Документация
  • SourceCode
    • Разработка
      • 3rdParty
      • Источник
    • Main
      • 3rdParty
      • Источник

Сборка тянет только основную ветвь и все, что под ней.

РЕДАКТИРОВАТЬ 2

Вот изображение вкладки Workspace в определении сборки: enter image description here

1 Ответ

22 голосов
/ 08 декабря 2011

Наконец я узнал, что происходит:

По сути, набор изменений, который можно увидеть на моем рисунке 1, всегда является последним набором изменений из всей Team Project Collection . Это свойство «SourceGetVersion» для объекта «BuildDetails» типа «IBuildDetails».

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

Что я сделал, чтобы добавить правильный номер набора изменений, так это то, что я создал пользовательскую операцию сборки, которая принимает ветвь, которая должна быть построена как входной параметр. Он выводит правильную ревизию. Упражнение находит правильный набор изменений, подключаясь к TFS и загружая журнал. Затем он просматривает все элементы в истории и выводит наибольший номер набора изменений. Вот код этой деятельности:

using System.Activities;
using System.Collections;
using System.Net;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.VersionControl.Client;
using Microsoft.TeamFoundation.Build.Client;

namespace SourceGetVersionActivity
{
    [BuildActivity(HostEnvironmentOption.All)]
    public sealed class SourceGetVersionActivity : CodeActivity<string>
    {
        // Define an activity input argument of type string
        public InArgument<string> Branch { get; set; }

        // If your activity returns a value, derive from CodeActivity<TResult>
        // and return the value from the Execute method.
        protected override string Execute(CodeActivityContext context)
        {
            // Obtain the runtime value of the Text input argument
            string branch = context.GetValue(this.Branch);

            ICredentials account = new NetworkCredential("Useranme", "password", "domain");

            // connect / authenticate with tfs
            TeamFoundationServer tfs = new TeamFoundationServer("http://tfs:8080/tfs/CollectionName", account);
            tfs.Authenticate();

            // get the version control service
            VersionControlServer versionControl = (VersionControlServer)tfs.GetService(typeof(VersionControlServer));

            IEnumerable changesets = versionControl.QueryHistory(branch, VersionSpec.Latest, 0, RecursionType.Full,
                null, null, null, int.MaxValue, false, false, false, false);

            int maxVersion = 0;

            foreach (Changeset c in changesets)
            {
                if (c.ChangesetId > maxVersion)
                {
                    maxVersion = c.ChangesetId;
                }
            }

            return string.Concat('C', maxVersion.ToString());
        }
    }
}

Я вызываю это действие как можно скорее (после действия GetBuild).

В основном в BuildProcessTemplate я добавил аргумент (строку) «Branch», который должен быть заполнен строкой, указывающей на верхнюю папку, которая создается. Пользовательское действие принимает это в качестве входных данных и выводит строку, которая является правильным идентификатором набора изменений. Свойство BuildDetail.SourceGetVersion будет переопределено правильным идентификатором набора изменений.

Мне действительно странно, что никто другой, похоже, не сталкивался с этой проблемой. Я не смог найти ни одного человека в интернете с такой же проблемой. В любом случае, я надеюсь, что этот ответ поможет кому-то еще и в будущем.

РЕДАКТИРОВАТЬ - Написание вышеуказанного кода непосредственно в Workflow Foundation:

Чтобы получить правильный набор изменений, используя более компактный код и избегая пользовательских активаций, также можно напрямую использовать Workflow Foundation. Ниже приведен «код» (делает именно то, что сделано в коде выше C #):

enter image description here

(1) Операция GetTeamProjectCollection получает текущую коллекцию. Я сохраняю его в переменной TeamProjectCollection (см. Внизу рисунка). Важное замечание: Переменная должна быть определена внутри этой последовательности, если вы определите ее во внешней области, произойдет ошибка: «Невозможно сериализовать тип« Microsoft.TeamFoundation.Client.TfsTeamProjectCollection ». Убедитесь, что тип является общедоступным и имеет либо конструктор по умолчанию или дескриптор экземпляра. "

(2) Foreach "changeset" в "TeamProjectCollection.GetService (Of VersionControlServer) .QueryHistory (Branch, VersionSpec.Latest, 0, RecursionType.Full, Nothing, Nothing, Nothing, Integer.MaxValue, False, False, False) .Cast (Of Changeset) () " Аргументом типа цикла Foreach является «Microsoft.TeamFoundation.VersionControl.Client.Changeset». Это выражение получает объект управления версиями из коллекции, вызывает его методом «QueryHistory», который возвращает IEnumerable со всеми наборами изменений.

(3) Итак, мы перебираем все наборы изменений и смотрим на ChangesetId. Затем сохраняем максимальный ChangesetId в переменную «maxId».

(4) В конце BuildDetails.SourceGetVersion = "C" + maxId.ToString (). «C» указывает, что версия является набором изменений.

Надеюсь, кто-то найдет этот фрагмент "кода" полезным!

Christian

...