Pregunta

Estoy usando CCNET en un proyecto de muestra con SVN como control de fuente.CCNET está configurado para crear una compilación en cada registro.CCNET usa MSBuild para construir el código fuente.

Me gustaría utilizar el último número de revisión para generar AssemblyInfo.cs mientras compila.¿Cómo puedo recuperar la última revisión de subversion y usar el valor en CCNET?

Editar:No estoy usando NAnt, solo MSBuild.

¿Fue útil?

Solución

CruiseControl.Net 1.4.4 ahora tiene una Etiquetadora de versión ensamblada, que genera números de versión compatibles con las propiedades del ensamblado .Net.

En mi proyecto lo tengo configurado como:

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

(Advertencia: assemblyVersionLabeller no comenzará a generar etiquetas basadas en revisiones svn hasta que se produzca una compilación activada por confirmación).

y luego consumir esto desde mis proyectos de MSBuild con 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>

Para completar, es igual de fácil para proyectos que usan NAnt en lugar de 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>

Otros consejos

Tienes básicamente dos opciones.O escribe un script simple que iniciará y analizará la salida de

Información de svn.exe --revisión HEAD

para obtener el número de revisión (luego generar AssemblyInfo.cs es bastante sencillo) o simplemente usar el complemento para CCNET.Aquí lo tienes:

Etiquetadora de revisión SVN es un complemento para CruiseControl.net que le permite generar etiquetas de CruiseControl para sus compilaciones, en función del número de revisión de su copia de trabajo de subversión.Esto se puede personalizar con un prefijo y/o números de versión mayor/menor.

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

Prefiero la primera opción porque solo tiene aproximadamente 20 líneas de código:

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

He escrito un archivo de compilación NAnt que se encarga de analizar la información SVN y crear propiedades.Luego uso esos valores de propiedad para una variedad de tareas de compilación, incluida la configuración de la etiqueta en la compilación.Utilizo este objetivo combinado con la etiquetadora de revisión SVN mencionada por lubos hasko con excelentes resultados.

<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>

encontré este proyecto en código de google.Esto es CCNET complemento para generar la etiqueta en CCNET.

El DLL se prueba con CCNET 1.3 pero funciona con CCNET 1.4 para mí.Estoy usando este complemento con éxito para etiquetar mi compilación.

Ahora pasemoslo a MSBuild...

Si prefieres hacerlo en el MSBuild lado sobre el CCNet configuración, se parece a la MSBuild Extensiones de tareas comunitarias SvnVersion La tarea podría ser la solución.

Actualmente lo estoy haciendo "manualmente" a través de una tarea prebuild-exec, usando mi cmdnetsvnrev herramienta, pero si alguien conoce una forma mejor integrada de ccnet de hacerlo, me encantaría saberlo :-)

Personalización de archivos csproj para generar automáticamente AssemblyInfo.cs
http://www.codeproject.com/KB/dotnet/Customizing_csproj_files.aspx

Cada vez que creamos un nuevo proyecto de C#, Visual Studio coloca el archivo AssemblyInfo.cs para nosotros.El archivo define los metadatos de ensamblaje como su versión, configuración o productor.

Encontré la técnica anterior para generar automáticamente AssemblyInfo.cs usando MSBuild.Publicaremos una muestra en breve.

No estoy seguro de si esto funciona con CCNET o no, pero he creado un Complemento de versión SVN Para el Incremento de versión de compilación proyecto en CodePlex.Esta herramienta es bastante flexible y se puede configurar para crear automáticamente un número de versión utilizando la revisión svn.No requiere escribir ningún código ni editar xml, así que ¡sí!

¡Espero que esto sea de ayuda!

Mi enfoque es utilizar el complemento antes mencionado para ccnet y una tarea nant echo para generar un VersionInfo.cs archivo que no contiene nada más que los atributos de la versión.solo tengo que incluir el VersionInfo.cs archivo en la compilación

La tarea de eco simplemente genera la cadena que le doy en un archivo.

Si hay una tarea de MSBuild similar, puede utilizar el mismo enfoque.Aquí está la pequeña tarea nant que uso:

<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>

Prueba esto:

<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>

Tenga en cuenta que no tengo mucha intimidad con MSBuild, por lo que mi secuencia de comandos probablemente no funcionará de inmediato y necesitará correcciones...

Basado en la solución skolimas, actualicé el script NAnt para actualizar también AssemblyFileVersion.¡Gracias a skolima por el código!

<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>

No tengo idea de dónde encontré esto.Pero encontré esto en Internet "en alguna parte".

Esto actualiza todos los archivos AssemblyInfo.cs antes de que se realice la compilación.

Funciona de maravilla.Todos mis archivos exe y dll aparecen como 1.2.3.333 (si "333" fuera la revisión SVN en ese momento). (Y la versión original en el archivo AssemblyInfo.cs aparecía como "1.2.3.0")


$(ProjectDir) (Donde reside mi archivo .sln)

$(SVNToolPath) (apunta a svn.exe)

son mis variables personalizadas, sus declaraciones/definiciones no se definen a continuación.


http://msbuildtasks.tigris.org/y/ohttps://github.com/loresoft/msbuildtaskstiene las tareas (FileUpdate y SvnVersion).


  <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>

EDITAR ------------------------------------------------- -

Lo anterior puede comenzar a fallar después de que su número de revisión SVN alcance 65534 o superior.

Ver:

Desactivar la advertencia CS1607

Aquí está la solución.

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

El resultado de esto debería ser:

En Windows/Explorador//Archivo/Propiedades…….

La versión de ensamblaje será 1.0.0.0.

La versión del archivo será 1.0.0.333 si 333 es la revisión SVN.

Ten cuidado.La estructura utilizada para los números de compilación es corta, por lo que tiene un límite sobre qué tan alto puede llegar su revisión.

En nuestro caso ya hemos superado el límite.

Si intenta ingresar el número de compilación 99.99.99.599999, la propiedad de versión del archivo en realidad aparecerá como 99.99.99.10175.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top