Auto increment your application version number using TextTransform


In part of my issue with the Xamarin which the newest code is not deployed whenever I run the project. I found that you can easily fix this when changing the version number in AssemblyInfo.cs
https://jaraio.blogspot.com/2020/04/auto-increment-version-number-using.html

To automate things, I look for a solution and found an answer in StackOverflow (huray! 🙌) were you can TextTransform to have some sort of a template and you can do some magical things to generate a customized file based on the codes you wrote inside of this .TT file.

Here's the StackOverflow link
https://stackoverflow.com/questions/826777/how-to-have-an-auto-incrementing-version-number-visual-studio

My problem with their solution is, if you noticed, it's pretty obvious.. You must include the content of the original AssemblyInfo.cs in the .tt file then just change the version lines.

I really don't like that, and I feel like somethings going to mess up sooner.
i.e. updating your Android permission requires you to update the .tt file as well or updating the assembly info like description, configuration, etc. requires you again to update the .tt file as well. Too much work.

So I made some changes. Since we already have a way to take the entire contents of the AssemblyInfo.cs file using File.ReadAllText then we'll use RegEx.Replace method to replace only the version lines and just overwrite the AssemblyInfo.cs file. This way, we are still updated whatever changes the Visual Studio has made in the AssemblyInfo.cs i.e added a new Android permission or we changed some assembly inforation the AsemblyInfo.cs directly in Visual Studio.

Here's the code. Save this file wherever your AssemblyInfo.cs is and name it AssemblyInfo.tt
<#@ template debug="true" hostspecific="true" language="C#" #>
<#@ output extension=".cs" #>
<#@ import namespace="System.IO" #>
<#@ import namespace="System.Text.RegularExpressions" #>
<#@ import namespace="System.Text" #>
<#
 string fileContent = File.ReadAllText(this.Host.ResolvePath("AssemblyInfo.cs"), Encoding.UTF8);

 try
 {
  int major = 1;
  int minor = 0;
  int revision = 0;
  int build = 0;

  string[] regexpats = new string[] {
   "AssemblyVersion\\(\"(?<major>\\d+)\\.(?<minor>\\d+)\\.(?<build>\\d+)\\.(?<revision>\\d+)\"\\)",
   "AssemblyFileVersion\\(\"(?<major>\\d+)\\.(?<minor>\\d+)\\.(?<build>\\d+)\\.(?<revision>\\d+)\"\\)"
  };
  string[] asmProp = new string[]
  {
   "AssemblyVersion",
   "AssemblyFileVersion"
  };

  for(int i = 0; i < regexpats.Length; i++)
  {
   string regexpattern = regexpats[i];
   RegexOptions options = ((RegexOptions.IgnorePatternWhitespace | RegexOptions.Multiline) | RegexOptions.IgnoreCase);
   Regex regex = new Regex(regexpattern, options);
   MatchCollection matches = regex.Matches(fileContent);

   if (regex.IsMatch(fileContent))
   {
    Match m = regex.Match(fileContent);

    major = Convert.ToInt32(m.Groups["major"].Value);
    minor = Convert.ToInt32(m.Groups["minor"].Value);
    build = Convert.ToInt32(m.Groups["build"].Value) + 1; // increment build number
    revision = Convert.ToInt32(m.Groups["revision"].Value);

    // increase revisio number if the build config is in release;
    if (this.Host.ResolveParameterValue("-", "-", "BuildConfiguration") == "Release") 
     revision++;

    fileContent = regex.Replace(fileContent, asmProp[i] + "(\"" + major + "." + minor + "." + build + "." + revision + "\")");
   }
  }
  
  WriteLine(fileContent);
 }
 catch(Exception ex)
 {
  WriteLine("/*" + ex.Message + "\r\n" + ex.StackTrace + "*/");
  WriteLine(fileContent);
 }
#>

Next step is to create a pre-build command
"%CommonProgramFiles(x86)%\microsoft shared\TextTemplating\14.0\TextTransform.exe" -a !!BuildConfiguration!$(Configuration) "$(ProjectDir)Properties\AssemblyInfo.tt"

And the final step is to make sure the Pre-Build command runs everytime even if you did not change anything in your code. Go to your executable project folder
i.e .Android or .IOS
and then open the project file. That at the very end, just before </Project> add this line
<PropertyGroup>
  <DisableFastUpToDateCheck>true</DisableFastUpToDateCheck>
</PropertyGroup> 
preview


and you're good to go.

I also found another solution where you can use PowerShell script and it's a one line solution! But I feel like TextTransform introduced me to some other possibilities and flexibilities I can use soon. So I'll stick with TextTransform solution.

Comments