2008-10-21 7 views
8

Mam wymóg instalacji wielu projektów konfiguracji sieciowej (przy użyciu VS2005 i ASP.Net/C#) w tym samym folderze wirtualnym. Projekty mają pewne odniesienia do zestawów (wszystkie systemy plików są tak skonstruowane, aby korzystać z tego samego folderu "bin"), co utrudnia wdrażanie zmian w tych złożeniach, ponieważ instalator MS nadpisze tylko zespoły, jeśli aktualnie zainstalowana wersja jest starsza niż wersja zainstalowana MSI.Jak używać MSBuild do aktualizowania informacji o wersji tylko po zmianie złożenia?

Nie sugeruję, że pesymistyczny schemat instalacji jest nieprawidłowy - tylko że stwarza problem w środowisku, w którym został mi dany pracować. Ponieważ istnieje spora liczba zwykłych zespołów i znaczna liczba programistów, którzy mogą zmienić wspólny zespół, ale zapomnieli zaktualizować jego numer wersji, próba ręcznego zarządzania wersją doprowadzi w końcu do ogromnego zamieszania w czasie instalacji.

W odwrotną stronę tej kwestii, ważne jest też, aby nie spontanicznie zaktualizować numery wersji i zastąpienie wszystkie wspólne zespoły z każdy zainstalować, ponieważ może (przynajmniej tymczasowo) niejasnych przypadkach, w których zostały wykonane rzeczywiste zmiany.

To, czego szukam, to sposób na aktualizację informacji o wersji zespołu (najlepiej przy użyciu MSBuild) tylko w przypadkach, w których składniki montażowe (moduły kodu, zasoby itp.) Zostały faktycznie zmienione.

Znalazłem kilka referencji, które są co najmniej częściowo istotne here (zadanie AssemblyInfo na MSDN) i here (wygląda podobnie do tego, czego potrzebuję, ale więcej niż dwa lata i bez jasnego rozwiązania).

Mój zespół również korzysta z kontroli wersji TFS, więc zautomatyzowane rozwiązanie powinno prawdopodobnie zawierać środki, za pomocą których można wyewidencjonować AssebmlyInfo podczas budowy.

Każda pomoc będzie mile widziana.

Z góry dziękuję.

Odpowiedz

10

Nie mogę odpowiedzieć na wszystkie pytania, ponieważ nie mam doświadczenia z TFS.

Ale mogę polecić lepsze podejście do aktualizacji plików AssemblyInfo.cs niż przy użyciu zadania AssemblyInfo. To zadanie wydaje się po prostu odtworzyć standardowy plik AssemblyInfo od zera i traci wszelkie niestandardowe części, które dodałeś.

Z tego powodu sugeruję, aby zajrzeć do zadania FileUpdate z projektu MSBuild Community Tasks. To może wyglądać na określonej treści w pliku i zastąpić ją w następujący sposób:

<FileUpdate 
Files="$(WebDir)\Properties\AssemblyInfo.cs" 
Regex="(\d+)\.(\d+)\.(\d+)\.(\d+)" 
ReplacementText="$(Major).$(ServicePack).$(Build).$(Revision)" 
Condition="'$(Configuration)' == 'Release'" 
/> 

Istnieje kilka sposobów można kontrolują inkrementację numer kompilacji. Ponieważ chcę tylko numer kompilacji, aby zwiększyć, jeżeli budowa jest całkowicie udany, używam metody 2-stopniową:

  • odczytać numer z pliku tekstowego (jedyną rzeczą w pliku jest liczbą) i dodać 1 bez zmiany pliku;
  • jako ostatni krok w procesie kompilacji, jeśli wszystko się powiedzie, zapisz zwiększoną liczbę z powrotem do pliku tekstowego.

Są zadania, takie jak ReadLinesFromFile, które mogą Ci w tym pomóc, ale uważam, że najłatwiej napisać mały niestandardowe zadanie:

using System; 
using System.IO; 
using Microsoft.Build.Framework; 
using Microsoft.Build.Utilities; 

namespace CredibleCustomBuildTasks 
{ 
    public class IncrementTask : Task 
    { 
     [Required] 
     public bool SaveChange { get; set; } 

     [Required] 
     public string IncrementFileName { get; set; } 

     [Output] 
     public int Increment { get; set; } 

     public override bool Execute() 
     { 
      if (File.Exists(IncrementFileName)) 
      { 
       string lines = File.ReadAllText(IncrementFileName); 
       int result; 
       if(Int32.TryParse(lines, out result)) 
       { 
        Increment = result + 1; 
       } 
       else 
       { 
        Log.LogError("Unable to parse integer in '{0}' (contents of {1})"); 
        return false; 
       } 
      } 
      else 
      { 
       Increment = 1; 
      } 

      if (SaveChange) 
      { 
       File.Delete(IncrementFileName); 
       File.WriteAllText(IncrementFileName, Increment.ToString()); 
      } 
      return true; 
     } 
    } 
} 

Używam tego przed FileUpdateTask dostać kolejną kompilację Numer:

<IncrementTask 
IncrementFileName="$(BuildNumberFile)" 
SaveChange="false"> 
    <Output TaskParameter="Increment" PropertyName="Build" /> 
</IncrementTask> 

i jako mojego ostatniego etapu (przed powiadomieniem inne) w budowie:

<IncrementTask 
IncrementFileName="$(BuildNumberFile)" 
SaveChange="true" 
Condition="'$(Configuration)' == 'Release'" /> 

Inne pytanie o to, jak zaktualizować numer wersji tylko po zmianie kodu źródłowego, zależy w dużej mierze od tego, jak proces budowania współdziała z kontrolą źródła. Zazwyczaj sprawdzanie zmian w plikach źródłowych powinno inicjować kompilację Continuous Integration. To jest ten, którego używa się do aktualizacji odpowiedniego numeru wersji.

0

Napisałem jedno zadanie custome, które można polecić poniższy kod. Stworzy to narzędzie, do którego możesz przekazać ścieżkę assemblyinfo Major, minor i numer kompilacji. możesz go zmodyfikować, aby uzyskać numer wersji. Ponieważ w moim przypadku zadanie to zostało wykonane przez programistę, użyłem go do przeszukania i ponownie zastąpiłem cały ciąg.

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.IO; 
using System.Text.RegularExpressions; 

namespace UpdateVersion 
{ 
    class SetVersion 
    { 
     static void Main(string[] args) 
     { 
      String FilePath = args[0]; 
      String MajVersion=args[1]; 
      String MinVersion = args[2]; 
      String BuildNumber = args[3]; 
      string RevisionNumber = null; 

      StreamReader Reader = File.OpenText(FilePath); 
      string contents = Reader.ReadToEnd(); 
      Reader.Close(); 

      MatchCollection match = Regex.Matches(contents, @"\[assembly: AssemblyVersion\("".*""\)\]", RegexOptions.IgnoreCase); 
      if (match[0].Value != null) 
      { 
       string strRevisionNumber = match[0].Value; 

       RevisionNumber = strRevisionNumber.Substring(strRevisionNumber.LastIndexOf(".") + 1, (strRevisionNumber.LastIndexOf("\"")-1) - strRevisionNumber.LastIndexOf(".")); 

       String replaceWithText = String.Format("[assembly: AssemblyVersion(\"{0}.{1}.{2}.{3}\")]", MajVersion, MinVersion, BuildNumber, RevisionNumber); 
       string newText = Regex.Replace(contents, @"\[assembly: AssemblyVersion\("".*""\)\]", replaceWithText); 

       StreamWriter writer = new StreamWriter(FilePath, false); 
       writer.Write(newText); 
       writer.Close(); 
      } 
      else 
      { 
       Console.WriteLine("No matching values found"); 
      } 
     } 
    } 
} 
0

Nienawidzę tego mówić, ale wydaje się, że można to robić źle. Jest znacznie łatwiejsze, jeśli generujesz wersje montażowe w locie, zamiast próbować je łatać.

Spójrz na https://sbarnea.com/articles/easy-windows-build-versioning/

Dlaczego ja sądzę, robisz to źle? * Kompilacja nie powinna modyfikować numeru wersji * jeśli dwukrotnie stworzysz ten sam zestaw zmian, powinieneś uzyskać te same numery kompilacji * jeśli wstawisz numer kompilacji do numeru kompilacji wywołań microsoft (prawidłowe nazewnictwo będzie to poziom PATCH) w końcu osiągnąć ograniczenie 65535.

Powiązane problemy