We are using TFS Build 2013 and I am configuring our build strategy. We want to keep it as default as possible, so we want to use the default build process template without any custom activities. Instead we have some Powershell scripts, which are connected to the default template. One of these scripts extracts the version number from the project to be build.
The problem: I want to parse this version number in the build number, so that our builds have a nice and meaningfull name (eg. Project - 2.1.2.46) and we dont have to change the build definition every release.
What I basically want to achieve, is that the outcome of my build script (below) is used as build number (format).
# Enable -Verbose option
[CmdletBinding()]
# Disable parameter
# Convenience option so you can debug this script or disable it in
# your build definition without having to remove it from
# the 'Post-build script path' build process parameter.
param([switch]$Disable)
if ($PSBoundParameters.ContainsKey('Disable'))
{
Write-Verbose "Script disabled; no actions will be taken on the files."
}
# Regular expression pattern to find the version in the assemblies
# and then apply it to the build number
$AssemblyFileVersionRegex = 'AssemblyFileVersion\("\d+\.\d+\.\d+\.\d+"'
# Make sure path to source code directory is available
if (-not $Env:TF_BUILD_SOURCESDIRECTORY)
{
Write-Error ("TF_BUILD_SOURCESDIRECTORY environment variable is missing.")
exit 1
}
elseif (-not (Test-Path $Env:TF_BUILD_SOURCESDIRECTORY))
{
Write-Error "TF_BUILD_SOURCESDIRECTORY does not exist: $Env:TF_BUILD_SOURCESDIRECTORY"
exit 1
}
Write-Verbose "TF_BUILD_SOURCESDIRECTORY: $Env:TF_BUILD_SOURCESDIRECTORY"
# Make sure build definition name is available
if (-not $Env:TF_BUILD_BUILDDEFINITIONNAME)
{
Write-Error ("TF_BUILD_BUILDDEFINITIONNAME environment variable is missing.")
exit 1
}
# Apply the version to the assembly property files
$files = gci $Env:TF_BUILD_SOURCESDIRECTORY -recurse -include "*Properties*", "Solution Items" |
?{ $_.PSIsContainer } |
foreach { gci -Path $_.FullName -Recurse -include CommonAssemblyInfo.*, AssemblyInfo.* }
if($files)
{
foreach ($file in $files) {
if(-not $Disable)
{
$fileContent = Get-Content $file
$found = $fileContent -match $AssemblyFileVersionRegex
if ($found)
{
Write-Verbose "Found in files: $found"
$VersionData = $found -replace [Regex]::Escape('[assembly: AssemblyFileVersion("'), ''
$VersionData = $VersionData -replace [Regex]::Escape('")]'), ''
Write-Verbose "Will apply $VersionData to build number"
$Env:TF_BUILD_BUILDNUMBER = $Env:TF_BUILD_BUILDDEFINITIONNAME + ' - ' + $VersionData
Write-Verbose "TF_BUILD_BUILDNUMBER: $Env:TF_BUILD_BUILDNUMBER"
exit 0
}
else
{
Write-Warning "No version number found in files. Build number will not be changed."
}
}
}
}
else
{
Write-Warning "Found no files."
}
With verbose logging turned on, I can see that my powershell script parses the right version number in the TF_BUILD_BUILDNUMBER variable. So, that shows me that my script is working. However, When the build is finished, the build number changed back to its default value, which was provided in the build definition.
Any help will be appreciated!
I found an answer myself: It is not possible to update the environment variables, e.g. TF_BUILD_BUILDNUMBER, using PowerShell and to use the updated values in your build again. It will always fall back to its default values, which are defined when the build is triggered.