We have for a long time used the TFSVersion custom build activity to stamp all our TFS builds with a unique version number that matches out build number. However, this only edits the AssemblyInfo.cs file. As we are now building more and more Windows 8 Store Apps we also need to edit the XML in the Package.appxmanifest files used to build the packages too. Just like a Wix MSI project it is a good idea the package version matches some aspect of the assemblies it contains. We need to automate the update of this manifest as people too often forget to increment the version, causing confusion all down the line.
Now I could have written a new TFS custom activity to do the job, or edited the existing one, but both options seemed a poor choice. We all know that custom activity writing is awkward and a pain to support going forward. So I decided to use the hooks in the 2013 generation build process template to just call a custom PowerShell script to do the job.
I added a PreBuildScript.PS1 file as a solution item to my solution.
I placed the following code in the file. It uses the TFS environment variables to get the build location and version; using these to find and edit the manifest files. The only gotcha is files on the build box are read only (it is a server workspace) so the manifest file has to be set it to allow it to be written back too.
\# get the build number, we assume the format is Myproject.Main.CI\_1.0.0.18290
\# where the version is set using the TFSVersion custom build activity (see other posts)
$buildnum = $env:TF\_BUILD\_BUILDNUMBER.Split('\_')\[1\]
\# get the manifest file paths
$files = Get-ChildItem -Path $env:TF\_BUILD\_BUILDDIRECTORY -Filter "Package.appxmanifest" -Recurse
foreach ($filepath in $files)
{
Write-Host "Updating the Store App Package '$filepath' to version ' $buildnum '"
# update the identity value
$XMLfile=NEW-OBJECT XML
$XMLfile.Load($filepath.Fullname)
$XMLFile.Package.Identity.Version=$buildnum
# set the file as read write
Set-ItemProperty $filepath.Fullname -name IsReadOnly -value $false
$XMLFile.save($filepath.Fullname)
}
Note that any output sent via Write-Host will only appear in the diagnostic log of TFS. If you use Write-Error (or errors are thrown) these messages will appear in the build summary, but the build will not fail, but will be marked as a partial success.
Once this file was checked in i was able to reference the file in the build template
The build could not be run and got my Windows 8 Store packages with the required version number