Using AssemblyInfo in Deployment Labels in VSTS Release Defintions
The Problem
Like I wrote in my previous post, the company I work for have used the assembly version for keeping track of deployments and we wanted to continue this practice when moving to use VSTS build and release management.
We currently use the Azure Cloud Services Classic to host our apps but we are looking at changing to an Azure Web App at some point in the future but that's a different story.
Once we created the builds, we moved onto creating a release definition in VSTS. Once the release definition is created you can link the artifact that the build created. This gives you access to the package and any linked files.
After the artifact is linked then the you can start updating the environment that will use the artifact. Since we are using an Azure Cloud Services Classic I add an Azure Cloud Service Deployment task to release the created package file. You see the code for the task here and the PowerShell here.
Once the task has been created I fill in the necessary settings that are outlined in red and this will release the package to the cloud service.
Pretty simple process so far. If you look at the bottom of the screenshot above you will see the option to set the Deployment Label. Setting this properly gives someone using the Azure portal the ability to see what version of the code that has been released easily.
You can see in the task setup screenshot that the Deployment label is defaulted to $(Build.BuildNumber). This is an alias of Release.Artifacts.{alias}.BuildNumber which will provide the build number of the artifact. I showed how to do this last week and so here the value would be something like 2018.6.1.0 2018-05-09 10h53.
We had a discussion about this format for the deployment label and we eventually decided to have the deployment version to read 2018.6.1.0 in a situation like this.
My Solution
Release definitions have variables similar to build definitions. I created a variable to hold the value called DeploymentLabel and replaced $(Build.BuildNumber) with $(DeploymentLabel) in the Cloud Service Deployment name. I can update this variable in a similar manner to updating a build number as outlined here. Now I need a way to get the AssemblyInfo from the project and use it in this variable.
Update the project
I added 2 new PowerShell files to the project into a folder called PowerShell.
The first is used to set a release phase variable, whose name will be passed into the script.
#
# Update_VSTS_Variable_To_Assembly_Version.ps1
#
param (
[parameter(Mandatory=$True)]
[string] $VariableName
)
$assemblyToUse = "REPLACE_WITH_VERSION"
Write-Host "##vso[task.setvariable variable=$VariableName]$assemblyToUse"
The second script replaces the REPLACE_WITH_VERSION string with the AssemblyVersion argument.
#
# Update_Files_With_Assembly_Version.ps1
#
Param (
[parameter(Mandatory=$True)]
[string] $AssemblyVersion
)
Write-Host "Update Update_VSTS_Variable_To_Assembly_Version.ps1"
(Get-Content -Path "Update_VSTS_Variable_To_Assembly_Version.ps1").Replace("REPLACE_WITH_VERSION", $AssemblyVersion) | Set-Content "Update_VSTS_Variable_To_Assembly_Version.ps1"
Update the build
I then added 2 new tasks to the build. The first was to run Update_Files_With_Assembly_Version.ps1 which will update Update_VSTS_Variable_To_Assembly_Version.ps1 with the correct assembly version.
The next tasks is to add a Copy Files task. I use this task to write all the .ps1 files in the PowerShell folder in the powershell folder in the artifact generated by the build. When I downloaded the created artifact, the "REPLACE_WITH_VERSION" string had been replaced with "2018.6.1.0".
Update the release
The artifact attached the release should now have a folder containing all the .ps1 files from the PowerShell folder in the build. I added a PowerShell task to run the Update_VSTS_Variable_To_Assembly_Version.ps1 file. An important thing to note that is hidden in the documentation is that "the updated variable value is scoped to the phase being executed and does not flow across phases" so this has to be run on each environment if you have more than one.
I pass in the name of the variable I wish to update with the assembly version and it's ready for use during the release.
Part of our update process involves checking whether our application updates successfully between releases. We're using the HTML5 application cache and we have to make sure that all files are updated to the new version. Testing that the new version updates successfully is important. We deploy an old version to a cloud service, run it in the browser, then deploy the new version and make sure the application works as expected after the update.
This method ensures that each build will have it's own version of Update_VSTS_Variable_To_Assembly_Version.ps1 with the relevant assembly version. If I want to deploy older versions I can use the same release process without having to worry about the version as long as I attach the right artifact.
There may be a simpler way to do this but this works fine so far. I'll keep looking for better solutions.
Comments ()