5

Ich habe zwei Projekte in CruiseControl.NET eingerichtet: CI Build und Nightly Build.Wie teile ich einen Label-Wert zwischen mehreren CruiseControl.NET-Builds?

Beide führen das gleiche NAnt-Skript aus, aber mit anderen Parametern.

Das CruiseControl.NET Etikett (derzeit von dem DefaultLabeler erzeugten) in Assembly als Build Teil der Version eingebettet (beispielsweise MajorVersion.MinorVersion.CCNET_Label.SVN_Revision).

Für eine konsistentere Version möchte ich, dass beide Projekte denselben CruiseControl.NET-Label-Wert verwenden.

Ich habe die Beschriftungen untersucht, die im Rahmen der CruiseControl.NET-Installation verfügbar sind, aber ich konnte keine finden, die das macht, was ich will.

Wie teile ich einen Label-Wert zwischen mehreren CruiseControl.NET-Builds?
Wenn es einen besseren Weg gibt, dies zu tun, würde ich gerne wissen.

Ich fand einen Weg. Siehe meine Antwort unten.

Antwort

9

Ich konnte keine existierende Lösung finden, um das zu tun, was ich brauchte, also schrieb ich einen benutzerdefinierten CruiseControl.NET-Etikettierer.

Hier ist, wie es gemacht wird:

  1. ein neues Projekt erstellen. Dies wird von CC.NET als Plugin-Bibliothek verwendet.

  2. Der Name der Ausgabe-DLL muss mit * ccnet. \ *. CruiseControl.plugin * übereinstimmen. Gehe zum Projekt Eigenschaften und ändern Sie "Assemblyname" in * ccnet. < Einsatzname hier > .CruiseControl.plugin *

  3. in Ihrem Projekt, fügen Sie Verweise auf die drei Baugruppen im CC.NET Server-Installationsverzeichnis (Standard: C: \ Programme \ CruiseControl.NET \ server) :
    • NetReflector.dll
    • ThoughtWorks.CruiseControl.Core.dll
    • ThoughtWorks.CruiseControl.Remote.dll

  4. Erstellen Sie eine neue öffentliche Klasse wie folgt aus:
     
    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. Ihr Projekt zusammenstellen und die DLL CC.NET Server-Installationsverzeichnis kopieren (Standard: C: \ Programme \ CruiseControl.NET \ server)

  6. Restart CC.NET Windows-Dienst

  7. eine Textdatei erstellen die aktuelle Build-Nummer

  8. zu speichern
  9. Fügen Sie der Projektdefinition in ccnet den neuen Labeler hinzu.config-Datei:
     
        <labeller type="sharedLabeller"> 
         <syncronisationFilePath>C:\Program Files\CruiseControl.NET\server\shared\buildnumber.txt</syncronisationFilePath> 
    <incrementOnFailure>false</incrementOnFailure> 
        </labeller> 
    
    


3

Ich lief in das gleiche Problem, aber ich fand, dass die <stateFileLabeller> in Verbindung mit dem <assemblyVersionLabeller> Verwendung erwies sich als eine viel einfachere Lösung sein.

Der einzige Grund für die Verwendung des stateFileLabels ist, dass Sie in einem Projekt kein Verzeichnis für Ihre Statusdateien angeben können, da CruiseControl.NET es nicht finden wird. Ich habe es im Standardverzeichnis gelassen, und es funktioniert großartig.

3

Ich habe die Klasse modifiziert Arnold machte es macht mehr ein Nachbau des 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; 
     } 
    } 
} 

Der Vorteil sollte sein, dass Sie jetzt Präfix sowie „incrementonfailure“ angeben. Außerdem habe ich eine "increment" -Eigenschaft hinzugefügt, die für Deployment-Builds verwendet werden kann, die die Build-Nummer überhaupt nicht erhöhen sollten. Wenn Sie es selbst modifizieren möchten, würde ich empfehlen, sich deren Implementierungen anzusehen: CruiseControl.NET repository folder containing labellers

+0

Schön! Abgestimmt. –

Verwandte Themen