2011-11-30 14 views
20

Jestem obecnie utworzenie Team Foundation Server 2010 i znalazłem bardzo dziwne zachowanie podczas wykonywania budowy:TFS2010 - Wrong changeset pojawiające się SourceGetVersion

Sytuację wyjaśnił: Mamy 2 oddziały

  • Development
  • Główne

Wszyscy deweloperzy sprawdzić w kodzie do jedynej gałęzi rozwojowej. Raz dziennie menedżer budowania łączy niektóre zestawy zmian z gałęzią główną. W oprogramowaniu deweloperskim działa ciągła kompilacja przy każdym uruchomieniu. W gałęzi głównej, raz dziennie (w nocy) uruchamiana jest kompilacja.

Teraz załóżmy, że zestawy zmian 1-100 są scalane z główną ramką o godzinie 17:00, co daje zestaw zmian 101 jako operację scalania. Niektórzy deweloperzy sprawdzają zestawy zmian 102-106 po godzinie 5 w gałęzi Rozwój. Teraz o godzinie 23:00 codzienna kompilacja jest automatycznie uruchamiana i działa w głównej gałęzi. Ostatnim changeset od głównego oddziału jest changeset 101. Jednak szczegóły Zbuduj pokazuje changeset 106:

enter image description here

mogę sobie wyobrazić, że takie zachowanie jest zamierzone, ponieważ jeśli sprawdzeniu changeset 106 na głównej gałęzi, w rzeczywistości otrzymasz zawartość zestawu zmian 101. Ale byłoby znacznie bardziej czytelne, gdyby podsumowanie kompilacji pokazało prawidłową liczbę.

Pytanie 1: Czy istnieje sposób na manipulowanie wynikiem informacji SourceGetVersion? Może poprzez szablon procesu budowania?

Drugi scenariusz, gdzie TFS zachowuje się dziwnie jest jeszcze gorzej: Kiedy kolejkowanie nowy build, istnieje możliwość wejścia do „Get Version” parametr, jak pokazano na poniższym rysunku:

enter image description here

Gdybym teraz kliknąć na „kolejce”, kompilacja jest wyzwalany i ponownie szczegółowo build wyprowadza changeset 106 choć specjalnie ustawić go dostać changeset 76.

Pytanie 2: Czy to błąd? Czy istnieje poprawka lub coś, aby to naprawić? Czy jest jakaś flaga opcji, którą należy ustawić?

Mam nadzieję, że ktoś wie o tym więcej. Naprawdę nie wierzę, że to błąd, ponieważ jest to tak ważna funkcja, że ​​inne osoby musiały ją wcześniej spotkać.

Dzięki za pomoc !! Christian

EDIT 1

Struktura folderów zespołu projektowego jest:

$ NazwaProjektu

  • BuildProcessTemplates
  • Dokumentacja
  • sourcecode
    • Development < - jest to oddział
      • 3rdParty
      • Źródło
    • główna < - to oddział
      • 3rdParty
      • Źródło

Konstrukcja ciągnie tylko gałąź główną i wszystko poniżej.

EDIT 2

Oto obraz na karcie Workspace w definicji produkcji: enter image description here

+0

1) Czy możesz podać więcej szczegółów na temat "manipulowania własnością SourceGetVersion"? Co chcesz robić? 2) Nie mam dostępu do kodu źródłowego w tej chwili, aby zobaczyć, co się stało w tym scenariuszu, ale czy kompilacja ma odpowiednią wersję i pokazuje "zły" numer zestawu zmian, czy kompilacja dostaje niewłaściwą wersję? –

+0

@DuatLe - Poprzez manipulację mam na myśli zmianę numeru, który generuje, tj. Zastąpienie "wyzwolonej kopii z ... dla zestawu zmian 106" przez "... dla zestawu zmian 101". Kod źródłowy, który faktycznie pobiera, wydaje się poprawny. Pokazuje tylko niewłaściwą. Wewnątrz bazy danych na serwerze TFS przechowuje również błędne informacje o zestawie zmian. – Christian

+0

Czy Twój build wyciąga tylko gałąź główną ze sterowania źródłami lub z głównej i deweloperskiej? –

Odpowiedz

22

końcu dowiedział się, co się dzieje:

Zasadniczo changeset, które mogą być na moim obrazku 1 zawsze znajduje się najnowszy zestaw zmian całej kolekcji projektów zespołu . Jest to właściwość "SourceGetVersion" na obiekcie "BuildDetails" typu "IBuildDetails".

Myślę, że jest to błąd, który można obejść: Po zmianie wartości BuildDetails.SourceGetVersion (która jest ciągiem znaków) na inną wartość, podsumowanie kompilacji wyświetli zaktualizowany ciąg znaków. Ponadto jest on następnie poprawnie zapisywany w bazie danych kolekcji.

To, co zrobiłem, aby dodać poprawny numer zestawu zmian, to utworzono niestandardową czynność kompilacji, która pobiera gałąź, która powinna być budowana jako parametr wejściowy. Wydaje poprawny zestaw zmian. Aktywność dowiaduje się o poprawnym zestawie zmian, łącząc się z TFS i pobierając historię. Następnie przegląda wszystkie pozycje w historii i wyświetla największy numer zestawu zmian. Oto kod tej aktywności:

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()); 
     } 
    } 
} 

Nazywam to działanie jak najszybciej (po aktywności GetBuild).

Zasadniczo w BuildProcessTemplate dodałem Argument (ciąg) "Branch", który musi zostać wypełniony ciągiem wskazującym na tworzony główny folder. Aktywność niestandardowa przyjmuje to jako dane wejściowe i wysyła ciąg znaków, który jest poprawnym identyfikatorem zestawu zmian. BuildDetail.Właściwość SourceGetVersion zostanie nadpisana przez poprawny identyfikator zestawu zmian.

Uważam, że to naprawdę dziwne, że nikt inny nie napotkał tego problemu. Nie mogłem znaleźć żadnej osoby w Internecie z tym samym problemem. W każdym razie, mam nadzieję, że ta odpowiedź pomoże komuś innemu w przyszłości.

EDIT - Zapis powyższy kod bezpośrednio w Workflow Foundation:

Aby uzyskać prawidłowe changeset użyciu kodu bardziej zwartą i unikanie niestandardowych rodzajów zajęć, możliwe jest również użycie Workflow Foundation bezpośrednio. Poniżej znajduje się "kod" (robi dokładnie to, co dzieje się w wyżej kod C#):

enter image description here

(1) Działalność GetTeamProjectCollection pobiera aktualną kolekcję. Zapisuję go wewnątrz zmiennej TeamProjectCollection (patrz u dołu obrazu). Ważne: Zmienna musi zostać zdefiniowana wewnątrz tej sekwencji, jeśli zdefiniujesz ją w zewnętrznym zasięgu, wystąpi błąd: "Nie można dokonać serializacji typu" Microsoft.TeamFoundation.Client.TfsTeamProjectCollection ". Sprawdź, czy typ jest publiczny i czy ma domyślny konstruktor lub deskryptor instancji. "

(2) Foreach "changeset" w „TeamProjectCollection.GetService (z VersionControlServer) .QueryHistory (oddziału, VersionSpec.Latest, 0, RecursionType.Full, nic, nic, nic, Integer.MaxValue, False, False, False) .Cast (of Changeset)() " TypArgument pętli Foreach to" Microsoft.TeamFoundation.VersionControl.Client.Changeset ". To wyrażenie pobiera obiekt kontroli wersji z kolekcji, nazywa to metodą "QueryHistory", która zwraca wartość IEnumerable ze wszystkimi zestawami zmian.

(3) W związku z tym powtarzamy wszystkie zestawy zmian i przeglądamy zestaw zmian. Następnie zapisz maksymalny identyfikator ChangesetId w zmiennej "maxId".

(4) Na końcu BuildDetails.SourceGetVersion = "C" + maxId.ToString(). "C" oznacza, że ​​wersja jest zestawem zmian.

Mam nadzieję, że ktoś znajdzie ten fragment "kodu" przydatny!

Christian

+1

+1 Bardzo dobre wyjaśnienie tego nieoczywistego problemu. –

+2

Niesamowite rozwiązanie (i tak jest to komentarz obcy, ale rozwiązanie to gwarantuje ...) –

+2

Doskonałe wyjaśnienie problemu i dobre rozwiązania, chociaż będą działać tylko w przypadku najnowszych wersji kodu. Nie będą działać dla wersji Gated Check-In ani dla wersji niestandardowych, gdzie budowana wersja nie jest najnowsza. – Ivan

Powiązane problemy