2008-08-04 11 views
39

Ich verwende CCNET für ein Beispielprojekt mit SVN als meine Quellcodeverwaltung. CCNET ist so konfiguriert, dass bei jedem Einchecken ein Build erstellt wird. CCNET verwendet MSBuild zum Erstellen des Quellcodes.Verwenden Sie SVN-Revision, um das Build in CCNET zu erstellen

Ich möchte die neueste Revisionsnummer verwenden, um AssemblyInfo.cs während des Kompilierens zu generieren. Wie kann ich die neueste Version von Subversion abrufen und den Wert in CCNET verwenden?

Bearbeiten: Ich verwende nicht NAnt - nur MSBuild.

Antwort

44

CruiseControl.Net 1.4.4 hat jetzt eine Assembly Version Labeller, die Versionsnummern generiert, die mit .Net-Baugruppeneigenschaften kompatibel sind.

In meinem Projekt habe ich es konfiguriert als:

<labeller type="assemblyVersionLabeller" incrementOnFailure="true" major="1" minor="2"/> 

(Caveat. assemblyVersionLabeller startet nicht SVN Revision Etiketten bis eine tatsächliche begehen ausgelöste Build auftritt Erzeugung)

und dann verbrauchen aus meinen MSBuild Projekten mit MSBuildCommunityTasks.AssemblyInfo:

<Import Project="$(MSBuildExtensionsPath)\MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets"/> 
<Target Name="BeforeBuild"> 
    <AssemblyInfo Condition="'$(CCNetLabel)' != ''" CodeLanguage="CS" OutputFile="Properties\AssemblyInfo.cs" 
    AssemblyTitle="MyTitle" AssemblyCompany="MyCompany" AssemblyProduct="MyProduct" 
    AssemblyCopyright="Copyright © 2009" ComVisible="false" Guid="some-random-guid" 
    AssemblyVersion="$(CCNetLabel)" AssemblyFileVersion="$(CCNetLabel)"/> 
</Target> 

aus Gründen der Vollständigkeit, es ist nur so einfach für Projekte mit NAnt Inste Anzeige von MSBuild:

<target name="setversion" description="Sets the version number to CruiseControl.Net label."> 
    <script language="C#"> 
     <references> 
      <include name="System.dll" /> 
     </references> 
     <imports> 
      <import namespace="System.Text.RegularExpressions" /> 
     </imports> 
     <code><![CDATA[ 
      [TaskName("setversion-task")] 
      public class SetVersionTask : Task 
      { 
       protected override void ExecuteTask() 
       { 
       StreamReader reader = new StreamReader(Project.Properties["filename"]); 
       string contents = reader.ReadToEnd(); 
       reader.Close(); 
       string replacement = "[assembly: AssemblyVersion(\"" + Project.Properties["CCNetLabel"] + "\")]"; 
       string newText = Regex.Replace(contents, @"\[assembly: AssemblyVersion\("".*""\)\]", replacement); 
       StreamWriter writer = new StreamWriter(Project.Properties["filename"], false); 
       writer.Write(newText); 
       writer.Close(); 
       } 
      } 
      ]]> 
     </code> 
    </script> 
    <foreach item="File" property="filename"> 
     <in> 
      <items basedir=".."> 
       <include name="**\AssemblyInfo.cs"></include> 
      </items> 
     </in> 
     <do> 
      <setversion-task /> 
     </do> 
    </foreach> 
</target> 
+3

+1 Super, das hat mir sehr geholfen. Ich aktualisierte Ihre Version für NAnt, um auch die AssemblyFileVersion und einige kleinere Dinge zu aktualisieren. Es ist als eine andere Antwort hier in diesem Thread enthalten. Vielen Dank! – galaktor

+0

Andere sollten diesen Vorbehalt nicht ablehnen; es ist sehr wichtig. Als Ergebnis gibt es viele Antworten auf den Webseiten, die sagen, dass dies nicht funktioniert. Scheint immer noch fehlerhaft, aber triggern, dass Build auf einen Check-in einmal und alles funktioniert wie erwartet danach. - Vielen Dank – Chuck

+0

Der Link zum Assembly Version Labeller ist defekt. – stephen

3

ich zur Zeit „von Hand“ es durch eine vorkompilierte-exec Aufgabe zu tun, mein cmdnetsvnrev-Tool, aber wenn jemand eine bessere Ccnet integrierte Art und Weise, es zu tun weiß, würde ich glücklich sein :-)

zu hören
4

Ich fand this Projekt auf Google-Code. Dies ist CCNET Plugin, um das Etikett in CCNET zu generieren. Die DLL ist mit CCNET 1.3 getestet, aber es funktioniert mit CCNET 1.4 für mich. Ich verwende dieses Plugin erfolgreich, um meinen Build zu kennzeichnen.

nun auf sie zu MSBuild vorbei ...

14

Sie haben grundsätzlich zwei Möglichkeiten. Entweder Sie schreiben, ein einfaches Skript, das ausgegeben wird gestartet und analysiert von

svn.exe info --revision HEAD

Revisionsnummer zu erhalten (dann zu erzeugen AssemblyInfo.cs ist ziemlich straight forward) oder einfach nur benutzen Plugin für CCNET. Hier ist sie:

SVN Revision Etikettierer ist ein Plugin für CruiseControl.NET, die Sie ermöglicht CruiseControl- Etiketten generieren für Ihre baut, basierend auf der Versionsnummer Ihrer Subversion Arbeitskopie. Diese kann mit einem Präfix und/oder Major/Minor-Versionsnummern angepasst werden.

http://code.google.com/p/svnrevisionlabeller/

ziehe ich die erste Option, da es nur etwa 20 Zeilen Code ist:

using System; 
using System.Diagnostics; 

namespace SvnRevisionNumberParserSample 
{ 
    class Program 
    { 
     static void Main() 
     { 
      Process p = Process.Start(new ProcessStartInfo() 
       { 
        FileName = @"C:\Program Files\SlikSvn\bin\svn.exe", // path to your svn.exe 
        UseShellExecute = false, 
        RedirectStandardOutput = true, 
        Arguments = "info --revision HEAD", 
        WorkingDirectory = @"C:\MyProject" // path to your svn working copy 
       }); 

      // command "svn.exe info --revision HEAD" will produce a few lines of output 
      p.WaitForExit(); 

      // our line starts with "Revision: " 
      while (!p.StandardOutput.EndOfStream) 
      { 
       string line = p.StandardOutput.ReadLine(); 
       if (line.StartsWith("Revision: ")) 
       { 
        string revision = line.Substring("Revision: ".Length); 
        Console.WriteLine(revision); // show revision number on screen      
        break; 
       } 
      } 

      Console.Read(); 
     } 
    } 
} 
4

Wenn Sie es auf der MSBuild Seite über die CCNet Config lieber tun, sieht aus wie die MSBuild Die Aufgabe SvnVersion der Community Tasks-Erweiterung könnte den Zweck erfüllen.

3

Dateien Anpassen csproj AssemblyInfo.cs automatisch generieren
http://www.codeproject.com/KB/dotnet/Customizing_csproj_files.aspx

Jedes Mal, wenn wir ein neues C# Projekt erstellen, Visual Studio legt es die AssemblyInfo.cs-Datei für uns. Die Datei definiert die Assembly-Metadaten wie ihre Version, Konfiguration oder Produzent.

Die obige Technik gefunden, um AssemblyInfo.cs mithilfe von MSBuild zu automatisieren. Wird die Probe in Kürze veröffentlichen.

4

Ich habe eine NAnt-Build-Datei geschrieben, die SVN-Informationen analysiert und Eigenschaften erstellt. Ich verwende dann diese Eigenschaftswerte für eine Vielzahl von Build-Aufgaben, einschließlich der Festlegung der Bezeichnung für den Build. Ich verwende dieses Ziel in Kombination mit dem von lubos hasko erwähnten SVN Revision Labeller mit großartigen Ergebnissen.

<target name="svninfo" description="get the svn checkout information"> 
    <property name="svn.infotempfile" value="${build.directory}\svninfo.txt" /> 
    <exec program="${svn.executable}" output="${svn.infotempfile}"> 
     <arg value="info" /> 
    </exec> 
    <loadfile file="${svn.infotempfile}" property="svn.info" /> 
    <delete file="${svn.infotempfile}" /> 

    <property name="match" value="" /> 

    <regex pattern="URL: (?'match'.*)" input="${svn.info}" /> 
    <property name="svn.info.url" value="${match}"/> 

    <regex pattern="Repository Root: (?'match'.*)" input="${svn.info}" /> 
    <property name="svn.info.repositoryroot" value="${match}"/> 

    <regex pattern="Revision: (?'match'\d+)" input="${svn.info}" /> 
    <property name="svn.info.revision" value="${match}"/> 

    <regex pattern="Last Changed Author: (?'match'\w+)" input="${svn.info}" /> 
    <property name="svn.info.lastchangedauthor" value="${match}"/> 

    <echo message="URL: ${svn.info.url}" /> 
    <echo message="Repository Root: ${svn.info.repositoryroot}" /> 
    <echo message="Revision: ${svn.info.revision}" /> 
    <echo message="Last Changed Author: ${svn.info.lastchangedauthor}" /> 
</target> 
2

Mein Ansatz ist es, die oben genannte Plugin für Ccnet und Nant Echo Aufgabe zu verwenden, um ein VersionInfo.cs Datei enthält nichts anderes als die Versionsattribute zu erzeugen. Ich muss nur die Datei VersionInfo.cs in den Build einfügen

Die Echo-Task gibt einfach die Zeichenfolge aus, die ich an eine Datei gebe.

Wenn es einen ähnlichen MSBuild-Task gibt, können Sie den gleichen Ansatz verwenden. Hier ist die kleine Nant Aufgabe, die ich verwenden:

<target name="version" description="outputs version number to VersionInfo.cs"> 
    <echo file="${projectdir}/Properties/VersionInfo.cs"> 
    [assembly: System.Reflection.AssemblyVersion("$(CCNetLabel)")] 
    [assembly: System.Reflection.AssemblyFileVersion("$(CCNetLabel)")] 
    </echo> 
</target> 

Versuchen Sie folgendes:

<ItemGroup> 
    <VersionInfoFile Include="VersionInfo.cs"/> 
    <VersionAttributes> 
     [assembly: System.Reflection.AssemblyVersion("${CCNetLabel}")] 
     [assembly: System.Reflection.AssemblyFileVersion("${CCNetLabel}")] 
    </VersionAttributes> 
</ItemGroup> 
<Target Name="WriteToFile"> 
    <WriteLinesToFile 
     File="@(VersionInfoFile)" 
     Lines="@(VersionAttributes)" 
     Overwrite="true"/> 
</Target> 

Bitte beachten Sie, dass ich mit MSBuild nicht sehr intim bin, so wird mein Skript wahrscheinlich nicht funktionieren out-of-the Kasten und Notwendigkeit Korrekturen ...

1

Seien Sie vorsichtig. Die Struktur, die für Build-Nummern verwendet wird, ist nur kurz, so dass Sie eine Obergrenze für die Höhe Ihrer Revision haben.

In unserem Fall haben wir das Limit bereits überschritten.

Wenn Sie versuchen, die Build-Nummer 99.99.99.599999 einzugeben, wird die Dateiversionseigenschaft tatsächlich als 99.99.99.10175 ausgegeben.

+0

ist es nicht der Fall, dass System.Version .Revision angibt, das ein int32 ist, und so können Sie das lieber als Minor und Major lesen, die eine maskierte Int32-Besetzung zu einem kurzen sind. –

2

Basierend auf der Lösung von skolima habe ich das NAnt-Skript aktualisiert, um auch die AssemblyFileVersion zu aktualisieren. Danke an skolima für den Code!

<target name="setversion" description="Sets the version number to current label."> 
     <script language="C#"> 
      <references> 
        <include name="System.dll" /> 
      </references> 
      <imports> 
        <import namespace="System.Text.RegularExpressions" /> 
      </imports> 
      <code><![CDATA[ 
        [TaskName("setversion-task")] 
        public class SetVersionTask : Task 
        { 
         protected override void ExecuteTask() 
         { 
         StreamReader reader = new StreamReader(Project.Properties["filename"]); 
         string contents = reader.ReadToEnd(); 
         reader.Close();      
         // replace assembly version 
         string replacement = "[assembly: AssemblyVersion(\"" + Project.Properties["label"] + "\")]"; 
         contents = Regex.Replace(contents, @"\[assembly: AssemblyVersion\("".*""\)\]", replacement);           
         // replace assembly file version 
         replacement = "[assembly: AssemblyFileVersion(\"" + Project.Properties["label"] + "\")]"; 
         contents = Regex.Replace(contents, @"\[assembly: AssemblyFileVersion\("".*""\)\]", replacement);           
         StreamWriter writer = new StreamWriter(Project.Properties["filename"], false); 
         writer.Write(contents); 
         writer.Close(); 
         } 
        } 
        ]]> 
      </code> 
     </script> 
     <foreach item="File" property="filename"> 
      <in> 
        <items basedir="${srcDir}"> 
          <include name="**\AssemblyInfo.cs"></include> 
        </items> 
      </in> 
      <do> 
        <setversion-task /> 
      </do> 
     </foreach> 
    </target> 
3

Ich bin mir nicht sicher, ob diese Arbeit mit CCNET oder nicht, aber ich habe ein SVN version plug-in für das Build Version Increment Projekt auf CodePlex erstellt. Dieses Tool ist ziemlich flexibel und kann so eingestellt werden, dass es automatisch eine Versionsnummer für Sie mit der svn-Revision erstellt. Es erfordert keinen Code zu schreiben oder XML zu bearbeiten, also yay!

Ich hoffe, das hilft!

2

Keine Ahnung, wo ich das gefunden habe. Aber ich habe das im Internet "irgendwo" gefunden.

Dies aktualisiert alle AssemblyInfo.cs-Dateien, bevor der Build stattfindet.

Funktioniert wie ein Charme. Alle meine exe und DLL zeigen sich als 1.2.3.333 (Wenn „333“ waren die SVN Revision zu der Zeit.) (Und die ursprüngliche Version in der AssemblyInfo.cs-Datei wurde aufgeführt als „1.2.3.0“)


$ (ProjectDir) (Wo ist meine SLN-Datei befindet)

$ (SVNToolPath) (Punkte svn.exe)

sind meine benutzerdefinierten Variablen, ihre Erklärungen/Definitionen sind nicht unten definiert.


http://msbuildtasks.tigris.org/ und/oder https://github.com/loresoft/msbuildtasks die (Fileupdate und svnversion) Aufgaben.


<Target Name="SubVersionBeforeBuildVersionTagItUp"> 

    <ItemGroup> 
     <AssemblyInfoFiles Include="$(ProjectDir)\**\*AssemblyInfo.cs" /> 
    </ItemGroup> 

    <SvnVersion LocalPath="$(MSBuildProjectDirectory)" ToolPath="$(SVNToolPath)"> 
     <Output TaskParameter="Revision" PropertyName="MySubVersionRevision" /> 
    </SvnVersion> 

    <FileUpdate Files="@(AssemblyInfoFiles)" 
      Regex="(\d+)\.(\d+)\.(\d+)\.(\d+)" 
      ReplacementText="$1.$2.$3.$(MySubVersionRevision)" /> 
    </Target> 

EDIT --------------------------------------- -----------

Der obige Fehler kann auftreten, nachdem die SVN-Revisionsnummer 65534 oder höher erreicht hat.

Siehe:

Turn off warning CS1607

Hier ist die Abhilfe ist.

<FileUpdate Files="@(AssemblyInfoFiles)" 
Regex="AssemblyFileVersion\(&quot;(\d+)\.(\d+)\.(\d+)\.(\d+)" 
ReplacementText="AssemblyFileVersion(&quot;$1.$2.$3.$(SubVersionRevision)" /> 

Das Ergebnis sollte sein:

In Windows/Explorer // Datei/Eigenschaften .......

Assembly Version wird 1.0.0.0 sein.

Die Dateiversion lautet 1.0.0.333, wenn 333 die SVN-Revision ist.

+0

Ich glaube, ich fand den ursprünglichen Ort, an dem ich es gefunden habe: http://geekswithblogs.net/mnf/archive/2009/07/03/msbuild-task-to-replace-content-in-text-files.aspx – granadaCoder