How to share tag value between multiple CruiseControl.NET assemblies?

I have two projects created in CruiseControl.NET: CI build and nightly build.

Both of them execute the same NAnt script, but with different parameters.

The CruiseControl.NET label (currently generated by DefaultLabeler) is built into AssemblyInfo as part of the version assembly (e.g. MajorVersion.MinorVersion.CCNET_Label.SVN_Revision).

For more consistent version control, I would like both projects to have the same CruiseControl.NET tag label value.

I researched the labels that are available as part of the CruiseControl.NET installation, but I could not find the one that does what I want.

How do I share a tag value between multiple CruiseControl.NET assemblies?
If there is a better way to do this, I would like to know.

I have found a way. See my answer below.

+5
source share
3 answers

I could not find an existing solution to do what I needed, so I ended up writing the usual CruiseControl.NET label.

Here's how to do it:

  •   
  • Create a new project. This will be used as a plugin library using CC.NET

      
  • DLL * ccnet.\*. CruiseControl.plugin *. " " * ccnet. < > .CruiseControl.plugin *

      
  • , CC.NET( : C:\Program Files\CruiseControl.NET\server):       
    •           
    • NetReflector.dll          
    • ThoughtWorks.CruiseControl.Core.dll          
    • ThoughtWorks.CruiseControl.Remote.dll      
          

        
  • , :
    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)
     }
    }
    


      
  • DLL CC.NET( : C:\Program Files\CruiseControl.NET\server)

      
  • CC.NET Windows

      


  •   
  • ccnet.config:
        <labeller type="sharedLabeller">
            <syncronisationFilePath>C:\Program Files\CruiseControl.NET\server\shared\buildnumber.txt</syncronisationFilePath>
    <incrementOnFailure>false</incrementOnFailure>
        </labeller>
    
    


+9

, , <stateFileLabeller> <assemblyVersionLabeller> .

stateFileLabeller , , CruiseControl.NET . , .

+3

, , :

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

, , "incrementonfailure". , "increment", , . , : CruiseControl.NET,

+3

All Articles