Change assembly version by team build

1. Create custom task by Visual Studio:


using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;

namespace MyBuildExtensions
{
    public class AssemblyInfo : Task
    {
        private const string Company = "Company name";
        private const string Copyright = "© 19xx - {0} Company name";

        [Required]
        public string FileNames { get; set; }

        [Required]
        public int MajorVersion { get; set; }

        [Required]
        public int MinorVersion { get; set; }

        [Required]
        public string Title { get; set; }

        [Required]
        public string Description { get; set; }

        public override bool Execute()
        {
            Log.LogMessage("FileName: {0}", FileNames);

            DateTime now = DateTime.Now;
            int year = now.Year;
            string copyright = string.Format(Copyright, year);

            Log.LogMessage("Copyright: {0}", copyright);

            string buildNumber = now.ToString("yyMM");
            string revision = now.ToString("dd");
            string version = string.Format("{0}.{1}.{2}.{3}", MajorVersion, MinorVersion, buildNumber, revision);

            Log.LogMessage("Version: {0}", version);

            List<string> fileList = new List<string>();
            if (FileNames.Contains(";"))
            {
                string[] files = FileNames.Split(';');
                fileList.AddRange(files);
            }
            else
            {
                fileList.Add(FileNames);
            }
            bool ok = false;
            foreach (string fileName in fileList)
            {
                ok = ReplaceProperties(fileName, version, copyright);
                if (!ok)
                {
                    break;
                }
            }
            return ok;
        }

        private bool ReplaceProperties(string fileName, string assemblyVersion, string assemblyCopyright)
        {
            bool ok = false;

            // remove readonly
            FileAttributes currentAttr = File.GetAttributes(fileName);
            File.SetAttributes(fileName, FileAttributes.Normal);

            // read file
            string content = File.ReadAllText(fileName, Encoding.UTF8);

            // replace properties
            ok = ReplaceProperty(ref content, Title, "AssemblyTitle", fileName);
            if (ok)
            {
                ok = ReplaceProperty(ref content, Title, "AssemblyProduct", fileName);
            }
            if (ok)
            {
                ok = ReplaceProperty(ref content, Description, "AssemblyDescription", fileName);
            }
            if (ok)
            {
                ok = ReplaceProperty(ref content, assemblyCopyright, "AssemblyCopyright", fileName);
            }
            if (ok)
            {
                ok = ReplaceProperty(ref content, assemblyVersion, "AssemblyVersion", fileName);
            }
            if (ok)
            {
                ok = ReplaceProperty(ref content, assemblyVersion, "AssemblyFileVersion", fileName);
            }

            // write back to file
            File.WriteAllText(fileName, content, Encoding.UTF8);

            // set readonly back
            File.SetAttributes(fileName, currentAttr);

            return ok;
        }

        private bool ReplaceProperty(ref string content, string newValue, string propertyName, string fileName)
        {
            string pattern = string.Format("{0}\\(\".*\"\\)", propertyName);
            string replacement = string.Format("{0}(\"{1}\")", propertyName, newValue);
            var re = new Regex(pattern, RegexOptions.Multiline);
            if (re.IsMatch(content))
            {
                content = re.Replace(content, replacement);
            }
            else
            {
                Log.LogError("The content of file {0} does not contain {1} attribute!", fileName, propertyName);
                return false;
            }
            return true;
        }
    }
}

You must add those references first:

  • Microsoft.Build.Framework.dll
  • Microsoft.Build.Utilities.v3.5.dll

2. Copy DLL that contains created task to Team Build server.
For example: C:\Program Files\MSBuild\ExtensionPack\MyBuildExtensions.dll

3. Modify project Team Build Type file (TFSBuild.proj):


<UsingTask AssemblyFile="$(MSBuildExtensionsPath)\\ExtensionPack\\MyBuildExtensions.dll" TaskName="MyBuildExtensions.AssemblyInfo"/>
<Target Name="BeforeCompile">
		
        <!-- specify assembly files to include for AssemblyInfo Task -->
        <CreateItem Include="$(SourcesRoot)\**\AssemblyInfo.*">
            <Output ItemName="AssemblyInfoFiles" TaskParameter="Include"/>
        </CreateItem>

	<MyBuildExtensions.AssemblyInfo
			FileNames="@(AssemblyInfoFiles)"
			MajorVersion="1"
			MinorVersion="2"
			Title="Product title"
			Description="Product description">			
	</MyBuildExtensions.AssemblyInfo>

</Target>

Where $(SourcesRoot) is custom defined property that points to the sources folder.

My versioning is in the format: Minor.Major.YYMM.DD

Advertisements