I have a need to update our build version number in our various *AssemblyInfo.cs files each and every time we do a release build of our products. I wanted to do this as a build step on our build server and I thought that Powershell would be the best way to do this given the fact we are use pSake as our build automation engine.
When I started to look for a pre-existing solution to this problem I assume there would be many, many examples on how to do this out on the net. I was both right and wrong. I was right from the point of view that there are many posts out there which tell you how to update the AssemblyInfo.cs files, such as this and this. However, pretty much every post I found either 1) only showed you how to update the AssemblyInfo.cs file with a PRE DETEREMINED version number or 2) Showed you how to get the current version off a .dll. Sadly these examples did not give me a full solution.
The issue I had was that our .dlls are not stored in source (well some are but they are going to be removed shortly) and I wanted to pull the current information out of the AssemblyInfo.cs file, use that as my base version and finally update the same AssemblyInfo.cs file with the new version (of course I plan to commit this update back to git).
Because of our needs I was not 100% able to find a solution I set out to build our own. I will say before I continue that one of my killer co-workers, James Manning, came to my rescue when my weak powershell skills started to get in my way.
My solution was as follows
function Increment-BuildNumbers
{
[CmdletBinding()]
param()
$assemblyPattern = "[0-9]+(\.([0-9]+|\*)){1,3}"
$assemblyVersionPattern = 'AssemblyVersion\("([0-9]+(\.([0-9]+|\*)){1,3})"\)'
$foundFiles = get-childitem .\*AssemblyInfo.cs -recurse
$rawVersionNumberGroup = get-content $foundFiles | select-string -pattern $assemblyVersionPattern | select -first 1 | % { $_.Matches }
$rawVersionNumber = $rawVersionNumberGroup.Groups[1].Value
$versionParts = $rawVersionNumber.Split('.')
$versionParts[3] = ([int]$versionParts[3]) + 1
$updatedAssemblyVersion = "{0}.{1}.{2}.{3}" -f $versionParts[0], $versionParts[1], $versionParts[2], $versionParts[3]
$assemblyVersion
foreach( $file in $foundFiles )
{
(Get-Content $file) | ForEach-Object {
% {$_ -replace $assemblyPattern, $updatedAssemblyVersion } |
} | Set-Content $file
}
Long story short, the code above will:
- Grab the first file which matches AssemblyInfo.cs in our folder.
- Grab the first line in the file that matches the $assemblyVersionPattern value above (aka [assembly: AssemblyVersion("1.9.5.0")]).
- Split it apart the version to get each part
- Grab the last value
- Increase it
- Recreate our version string
- Open ALL the found files in my folder which match the naming pattern (use use shared AssemblyInfo.cs files across all our projects)
- Replace the needed pattern in the file w/ the new version
- Rejoice :)
This solution may not be elegant, and I am sure there are a dozen different ways to solve this issue but this is the one that IMO best met our needs and was workable.
Till next time,
Posted
11-28-2012 5:27 PM
by
Derik Whittaker