5

Tengo dos proyectos configurados en CruiseControl.NET: compilación CI y compilación nocturna.¿Cómo comparto el valor de una etiqueta entre varias compilaciones de CruiseControl.NET?

Ambos ejecutan el mismo script NAnt, pero con diferentes parámetros.

La etiqueta CruiseControl.NET (actualmente generada por el DefaultLabeler) está incrustado en AssemblyInfo como la parte de construcción de la versión (por ejemplo, MajorVersion.MinorVersion.CCNET_Label.SVN_Revision).

Para versiones más consistentes Me gustaría que ambos proyectos compartan el mismo valor de etiqueta CruiseControl.NET.

He investigado las etiquetadoras que están disponibles como parte de la instalación de CruiseControl.NET, pero no he podido encontrar una que haga lo que quiero.

¿Cómo comparto el valor de una etiqueta entre varias compilaciones de CruiseControl.NET?
Si hay una mejor manera de hacerlo, me gustaría saberlo.

Encontré una manera. Ver mi respuesta a continuación.

Respuesta

9

No pude encontrar una solución existente que hiciera lo que necesitaba, así que terminé escribiendo una etiquetadora CruiseControl.NET personalizada.

Así es como se hace:

  1. Crear un nuevo proyecto. Esto se usará como una biblioteca de complementos por CC.NET

  2. El nombre de la DLL de salida debe coincidir con * ccnet. \ *. CruiseControl.plugin *. Vaya a las propiedades del proyecto y cambie "Nombre del ensamblado" a * ccnet. < insertar nombre aquí > .CruiseControl.plugin *

  3. En su proyecto, agregar referencias a los tres montajes que se encuentran en el directorio de instalación del servidor CC.NET (por defecto es: C: \ Archivos de programa \ CruiseControl.NET \ servidor) :
    • NetReflector.dll
    • ThoughtWorks.CruiseControl.Core.dll
    • ThoughtWorks.CruiseControl.Remote.dll

  4. crear una nueva clase pública como este:
     
    using ThoughtWorks.CruiseControl.Core; 
    using ThoughtWorks.CruiseControl.Remote; 
    
    // this is the labeller name that will be used in ccnet.config 
    [ReflectorType("customLabeller")] 
    public class CustomLabeller : ILabeller 
    { 
    [ReflectorProperty("syncronisationFilePath", Required = true)] 
    public string SyncronisationFilePath { get; set; } 
    
    #region ILabeller Members 
    
    public string Generate(IIntegrationResult previousResult) 
    { 
        if (ShouldIncrementLabel(previousResult)) 
        return IncrementLabel(); 
    
        if (previousResult.Status == IntegrationStatus.Unknown) 
        return "0"; 
    
        return previousResult.Label; 
    } 
    
    public void Run(IIntegrationResult result) 
    { 
        result.Label = Generate(result); 
    } 
    
    #endregion 
    
    private string IncrementLabel() 
    { 
        if(!File.Exists(SyncronisationFilePath)) 
        return "0"; 
    
        using (FileStream fileStream = File.Open(SyncronisationFilePath, 
         FileMode.OpenOrCreate, 
         FileAccess.ReadWrite, 
         FileShare.None)) 
        { 
        // read last build number from file 
        var bytes = new byte[fileStream.Length]; 
        fileStream.Read(bytes, 0, bytes.Length); 
    
        string rawBuildNumber = Encoding.ASCII.GetString(bytes); 
    
        // parse last build number 
        int previousBuildNumber = int.Parse(rawBuildNumber); 
        int newBuildNumber = previousBuildNumber + 1; 
    
        // increment build number and write back to file 
        bytes = Encoding.ASCII.GetBytes(newBuildNumber.ToString()); 
    
        fileStream.Seek(0, SeekOrigin.Begin); 
        fileStream.Write(bytes, 0, bytes.Length); 
    
        return newBuildNumber.ToString(); 
        } 
    } 
    
    private static bool ShouldIncrementLabel(IIntegrationResult previousResult) 
    { 
        return (previousResult.Status == IntegrationStatus.Success || 
        previousResult.Status == IntegrationStatus.Unknown) 
    } 
    } 
    


  5. compilar el proyecto y copiar el archivo DLL en el directorio de instalación del servidor CC.NET (por defecto es: C: \ Archivos de programa \ CruiseControl.NET \ servidor) servicio

  6. reinicio de Windows CC.NET

  7. Crear un archivo de texto para almacenar el número de compilación actual

  8. Agregue la nueva etiquetadora a su definición de proyecto en ccnet.fichero de configuración:
     
        <labeller type="sharedLabeller"> 
         <syncronisationFilePath>C:\Program Files\CruiseControl.NET\server\shared\buildnumber.txt</syncronisationFilePath> 
    <incrementOnFailure>false</incrementOnFailure> 
        </labeller> 
    
    


3

me encontré con el mismo problema, pero he encontrado que el uso de la <stateFileLabeller> en conjunto con el <assemblyVersionLabeller> demostrado ser una solución mucho más simple.

El único problema con el uso de stateFileLabeller es que no puede especificar un directorio para los archivos de estado en un proyecto, porque CruiseControl.NET no lo encontrará. Lo dejé en el directorio predeterminado y funciona muy bien.

3

He modificado la clase Arnold hizo lo que hace más de una réplica de la defaultlabeller:

using System.IO; 
using System.Text; 

using Exortech.NetReflector; 
using ThoughtWorks.CruiseControl.Core; 
using ThoughtWorks.CruiseControl.Remote; 

// This namespace could be altered and several classes could be put into the same if you'd want to combine several plugins in one dll 
namespace ccnet.SharedLabeller.CruiseControl.plugin 
{ 
    [ReflectorType("sharedLabeller")] 
    public class SharedLabeller : ILabeller 
    { 
     /// <summary> 
     /// The path where the file that holds the shared label should be located 
     /// </summary> 
     /// <default>none</default> 
     [ReflectorProperty("sharedLabelFilePath", Required = true)] 
     public string SharedLabelFilePath { get; set; } 

     /// <summary> 
     /// Any string to be put in front of all labels. 
     /// </summary> 
     [ReflectorProperty("prefix", Required = false)] 
     public string Prefix { get; set; } 

     /// <summary> 
     /// If true, the label will be incremented even if the build fails. Otherwise it will only be incremented if the build succeeds. 
     /// </summary> 
     [ReflectorProperty("incrementOnFailure", Required = false)] 
     public bool IncrementOnFailure { get; set; } 

     /// <summary> 
     /// If false, the label will never be incremented when this project is builded. This is usefull for deployment builds that 
     /// should use the last successfull of two or more builds 
     /// </summary> 
     [ReflectorProperty("increment", Required = false)] 
     public bool Increment { get; set; } 

     /// <summary> 
     /// Allows you to set the initial build number. 
     /// This will only be used when on the first build of a project, meaning that when you change this value, 
     /// you'll have to stop the CCNet service and delete the state file. 
     /// </summary> 
     /// <default>0</default> 
     [ReflectorProperty("initialBuildLabel", Required = false)] 
     public int InitialBuildLabel { get; set; } 

     public SharedLabeller() 
     { 
      IncrementOnFailure = false; 
      Increment = true; 
      InitialBuildLabel = 0; 
     } 

     #region ILabeller Members 

     public string Generate(IIntegrationResult integrationResult) 
     { 
      if (ShouldIncrementLabel(integrationResult.LastIntegration)) 
      { 
       return Prefix + this.GetLabel(); 
      } 
      else 
      { 
       return integrationResult.LastIntegration.Label; 
      } 
     } 

     public void Run(IIntegrationResult integrationResult) 
     { 
      integrationResult.Label = Generate(integrationResult); 
     } 

     #endregion 

     /// <summary> 
     /// Get and increments the label, unless increment is false then it only gets the label 
     /// </summary> 
     /// <returns></returns> 
     private string GetLabel() 
     { 
      ThoughtWorks.CruiseControl.Core.Util.Log.Debug("About to read label file. Filename: {0}", SharedLabelFilePath); 
      using (FileStream fileStream = File.Open(this.SharedLabelFilePath, 
        FileMode.OpenOrCreate, 
        FileAccess.ReadWrite, 
        FileShare.None)) 
      { 
       // Read last build number from file 
       var bytes = new byte[fileStream.Length]; 
       fileStream.Read(bytes, 0, bytes.Length); 

       string rawBuildNumber = Encoding.UTF8.GetString(bytes); 

       // Parse last build number 
       int previousBuildNumber; 
       if (!int.TryParse(rawBuildNumber, out previousBuildNumber)) 
       { 
        previousBuildNumber = InitialBuildLabel - 1; 
       } 

       if (!Increment) 
       { 
        return previousBuildNumber.ToString(); 
       } 

       int newBuildNumber = previousBuildNumber + 1; 

       // Increment build number and write back to file 
       bytes = Encoding.UTF8.GetBytes(newBuildNumber.ToString()); 

       fileStream.Seek(0, SeekOrigin.Begin); 
       fileStream.Write(bytes, 0, bytes.Length); 

       return newBuildNumber.ToString(); 
      } 
     } 

     private bool ShouldIncrementLabel(IntegrationSummary integrationSummary) 
     { 
      return integrationSummary == null || integrationSummary.Status == IntegrationStatus.Success || IncrementOnFailure; 
     } 
    } 
} 

El beneficio debe ser que ahora se puede especificar el prefijo, así como "incrementonfailure". También he agregado una propiedad de "incremento" que se puede usar para las compilaciones de implementación que no deberían incrementar el número de compilación en absoluto. Si desea modificarlo usted mismo, le aconsejaría echar un vistazo a sus implementaciones: CruiseControl.NET repository folder containing labellers

+0

¡Bonito! Votado arriba. –

Cuestiones relacionadas