5

J'ai deux projets mis en place dans CruiseControl.NET: Construction CI et génération nocturne.Comment partager une valeur d'étiquette entre plusieurs versions de CruiseControl.NET?

Les deux exécutent le même script NAnt, mais avec des paramètres différents.

L'étiquette CruiseControl.NET (actuellement générée par le DefaultLabeler) est noyé dans AssemblyInfo que la partie de génération de la version (par exemple, MajorVersion.MinorVersion.CCNET_Label.SVN_Revision).

Pour une version plus cohérente, j'aimerais que les deux projets partagent la même valeur d'étiquette CruiseControl.NET.

J'ai analysé les étiqueteurs disponibles dans le cadre de l'installation de CruiseControl.NET, mais je n'ai pas pu en trouver un qui fasse ce que je veux.

Comment partager une valeur d'étiquette entre plusieurs versions de CruiseControl.NET?
S'il y a une meilleure façon de le faire, j'aimerais savoir.

J'ai trouvé un moyen. Voir ma réponse ci-dessous.

Répondre

9

Je ne pouvais pas trouver une solution existante pour faire ce dont j'avais besoin, j'ai donc fini par écrire une imprimante personnalisée CruiseControl.NET.

Voilà comment cela se fait:

  1. Créer un nouveau projet. Ceci sera utilisé comme une bibliothèque de plugins par CC.NET

  2. Le nom de la DLL de sortie doit correspondre à * ccnet. \ *. CruiseControl.plugin *. Passez au projet et remplacez "Nom de l'assemblage" par "ccnet". < insérer le nom ici > .CruiseControl.plugin *

  3. Dans votre projet, ajouter des références aux trois ensembles trouvés dans le répertoire d'installation du serveur CC.NET (par défaut: C: \ Program Files \ CruiseControl.NET \ server) :
    • NetReflector.dll
    • ThoughtWorks.CruiseControl.Core.dll
    • ThoughtWorks.CruiseControl.Remote.dll

  4. Créer une nouvelle classe publique comme celle-ci:
     
    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. compilez votre projet et copiez le DLL dans le répertoire d'installation du serveur CC.NET (par défaut: C: \ Program Files \ CruiseControl.NET \ server)

  6. Redémarrez CC.NET service Windows

  7. Créez un fichier texte pour stocker le numéro de version actuelle

  8. Ajoutez la nouvelle étiqueteuse à votre définition de projet dans ccnet.fichier de configuration:
     
        <labeller type="sharedLabeller"> 
         <syncronisationFilePath>C:\Program Files\CruiseControl.NET\server\shared\buildnumber.txt</syncronisationFilePath> 
    <incrementOnFailure>false</incrementOnFailure> 
        </labeller> 
    
    


3

je suis tombé sur la même question, mais je trouve que l'utilisation du <stateFileLabeller> conjointement avec le <assemblyVersionLabeller> avéré être une solution beaucoup plus simple. Le seul problème avec le stateFileLabeller est que vous ne pouvez pas spécifier un répertoire pour vos fichiers d'état dans un projet, car CruiseControl.NET ne le trouvera pas. Je l'ai laissé dans le répertoire par défaut, et ça marche très bien.

3

J'ai modifié la classe Arnold fit le rendant plus d'une réplique du 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; 
     } 
    } 
} 

L'avantage devrait être que vous pouvez maintenant spécifier le préfixe ainsi que « incrementonfailure ». J'ai également ajouté une propriété "increment" qui peut être utilisée pour les builds de déploiement qui ne doivent pas incrémenter le nombre de builds du tout. Si vous voulez le modifier vous-même, je vous conseille de jeter un oeil à leurs implémentations: CruiseControl.NET repository folder containing labellers

+0

Nice! Voté –

Questions connexes