June 23, 2014

Setup a continuous integration for Sitecore with TDS - TFS 2013 and Octopus - Step 4: Align the version number

This is a last post of a series of post about the setup of a continuous integration for Sitecore. If you have miss the 4 previous post, here is the links:
  1. Setup a continuous integration for Sitecore with TDS - TFS 2013 and Octopus - Architecture
  2. Setup a continuous integration for Sitecore with TDS - TFS 2013 and Octopus - Step 1: Customize the TFS workflow
  3. Setup a continuous integration for Sitecore with TDS - TFS 2013 and Octopus - Step 2: Configure TFS
  4. Setup a continuous integration for Sitecore with TDS - TFS 2013 and Octopus - Step 3: Configure octopus
If you stop here you workflow should be ok but, I had another requirement: the version number. I would like to have the same reference number into every steps of my process:
  • The build number who appear in TFS
  • The assemblies files
  • The nuget packages
  • The octopus versions
To do that:
  1. Change the "Build number format" into the section "5. Advanced" of the TFS build definition by: $(BuildDefinitionName)_$(Date:1MMdd)$(Rev:.r). Be carefull with this number format. You can see that I have use 1MMdd and not YYYYMMdd as it is by default. The reason of that is that the Assembly number must between 0 and 65535. So you have a solution for the next 6 year by changing the 1 by another number :)
  2. Add a file .ps1 anywhere in the sources with the following content and do a check-in in TFS
  3. In the section 2.5 "Pre-build script path", refer to the powershell file you have created.
  4. In the section 2.5 "Pre-build script arguments", put the following value "-assemblyVersion 1.1.J.B -fileAssemblyVersion 1.1.J.B -nugetVersion 1.1.J.B". This mean that the powersell will replace the .J.B of the different files (assembly, assemblyVersion, nuget) by the same numbers as the build number of TFS
Here is the content of the powershell script to rename the versions:
param
(
 [string]$assemblyVersion,
 [string]$fileAssemblyVersion,
 [string]$nugetVersion
)

#Update the AssemblyInfo.cs and the .nuspec file to replace the X.X.J.B version number by the correct one depending of the number from TFS
function Update-SourceVersion
{
  param
  (
    [string]$SrcPath,
    [string]$assemblyVersion, 
    [string]$fileAssemblyVersion,
 [string]$nugetVersion
  ) 
  
    $buildNumber = $env:TF_BUILD_BUILDNUMBER
 Write-Host "env:TF_BUILD_BUILDNUMBER: $buildNumber"
 
    if ($buildNumber -eq $null)
    {
        $buildIncrementalNumber = 0
    }
    else
    {
        $splitted = $buildNumber.Split('.')
        $buildIncrementalNumber = $splitted[$splitted.Length - 1]
    }
    
    if ($fileAssemblyVersion -eq "")
    {
        $fileAssemblyVersion = $assemblyVersion
    }
     
    Write-Host "Executing Update-SourceVersion in path $SrcPath, Version is $assemblyVersion and File Version is $fileAssemblyVersion"
    
    
    $AllVersionFiles = Get-ChildItem $SrcPath AssemblyInfo.cs -recurse
    
     
    $jdate = Get-Date -format 1MMdd
 
 Write-Host "Infos: jdate: $jdate, buildIncrementalNumber: $buildIncrementalNumber"
 
    $assemblyVersion = $assemblyVersion.Replace("J", $jdate).Replace("B", $buildIncrementalNumber)
    $fileAssemblyVersion = $fileAssemblyVersion.Replace("J", $jdate).Replace("B", $buildIncrementalNumber)
     
    Write-Host "Transformed Assembly Version is $assemblyVersion and Transformed File Version is $fileAssemblyVersion"
        
    foreach ($file in $AllVersionFiles) 
    { 
        Write-Host "Modifying file " + $file.FullName
        #save the file for restore
        $backFile = $file.FullName + "._ORI"
        $tempFile = $file.FullName + ".tmp"
        Copy-Item $file.FullName $backFile
        #now load all content of the original file and rewrite modified to the same file
        Get-Content $file.FullName |
        %{$_ -replace 'AssemblyVersion\("[0-9]+(\.([0-9]+|\*)){1,3}"\)', "AssemblyVersion(""$assemblyVersion"")" } |
        %{$_ -replace 'AssemblyFileVersion\("[0-9]+(\.([0-9]+|\*)){1,3}"\)', "AssemblyFileVersion(""$fileAssemblyVersion"")" }  > $tempFile
        Move-Item $tempFile $file.FullName -force
    }
 
 $nugetVersion = $nugetVersion.Replace("J", $jdate).Replace("B", $buildIncrementalNumber)
    Write-Host "Transformed Nuspec Version is $nugetVersion"
  
    $AllNugetFiles = Get-ChildItem $SrcPath *.nuspec -recurse
 $replaceExp = '<file src="$1" target="$2.' + $nugetVersion + '.update" />'
 
 foreach ($file in $AllNugetFiles) 
    { 
        Write-Host "Modifying file " + $file.FullName
        #save the file for restore
        $backFile = $file.FullName + "._ORI"
        $tempFile = $file.FullName + ".tmp"
        Copy-Item $file.FullName $backFile
        #now load all content of the original file and rewrite modified to the same file
        Get-Content $file.FullName |
        %{$_ -replace '<version>[0-9]+(\.([0-9]+|\*)){1,3}</version>', "<version>$nugetVersion</version>" }  |
  %{$_ -replace '<file src="(.*NationalLottery\.DeHub\..*)" target="(.*)\.[0-9]+(\.([0-9]+|\*|J|B)){1,3}.update" />', $replaceExp } > $tempFile
        Move-Item $tempFile $file.FullName -force
    } 
}

Write-Host "Running Pre Build Scripts"
 
$scriptRoot = Split-Path -Parent -Path $MyInvocation.MyCommand.Definition

$scriptRootBuildFunctions = "$scriptRoot\TFSUtils.psm1"
Write-Host "Script root: $scriptRootBuildFunctions"

if ($assemblyVersion -eq "")
{
 $assemblyVersion = "1.1.0.0"
 $fileAssemblyVersion = "1.1.J.B"
}

$srcPath = "$scriptRoot/../"

Update-SourceVersion $srcPath $assemblyVersion $fileAssemblyVersion $nugetVersion

If you use the script to create and deploy the Octopus packages as describe in the previous post, don't forget to complete the "Post-build script arguments" to "-releaseVersion 1.1.J.B" to use the same versioning system and having this number as release number in Octopus.

Ok that is it now. I hope that this tutorial will help you in your deployment process.
You also have a video presented to the Sitecore Virtual User Group who could be useful for it here: http://sitecoreug.org/events/January

Here is the index of all the post who compose this tutorial:
  1. Setup a continuous integration for Sitecore with TDS - TFS 2013 and Octopus - Architecture
  2. Setup a continuous integration for Sitecore with TDS - TFS 2013 and Octopus - Step 1: Customize the TFS workflow
  3. Setup a continuous integration for Sitecore with TDS - TFS 2013 and Octopus - Step 2: Configure TFS
  4. Setup a continuous integration for Sitecore with TDS - TFS 2013 and Octopus - Step 3: Configure octopus
  5. Setup a continuous integration for Sitecore with TDS - TFS 2013 and Octopus - Step 4: Align the version number

1 comment:

  1. I think this is an great blogs. Such a very informative and creative contents. These concept is good for these knowledge.I like it and help me to development very well.Thank you for this brief explanations.
    Dot Net Training in Chennai

    ReplyDelete