What happened to the "Reason" property in TFS 2010 Builds - tfs

When we used TFS 2008 (SP1) we used to be able to access the "Reason" MSBuild property, which contained the reason the build was running. This was available as soon as the build started, so no task/target needed to fetch it. Now we're using TFS 2010 (and MSBuild / Upgrade Template, not Workflow) and the property is no longer populated. I could write a custom task to retrieve the info from IBuildDetail, but isn't there a property immediately available to my MSBuild scripts? I used to be able to do conditional MSBuild script imports based on the build reason and this will not work if I have to use a task/target to fetch the reason.

You are still using MSBuild scripts, so I assume you are using the Upgrade Template. You can clone/edit or modify the Upgrade Template so that the template takes the current build reason and passes it to MSBuild via the Run TfsBuild for Configuration Folder activity. Open the template for edit in Visual Studio and do the following:
Select the Run On Agent activity and go to the Variables tab. Create a new variable to store the build reason and populate its default value using info from the IBuildDetail. Add something like the following to the list of variables:
Name: currentBuildReason
Variable type: String
Scope: Run On Agent
Default: BuildDetail.Reason.ToString()
Next, click on the Properties dialog for the Run TfsBuild for Configuration Folder activity. Select the CommandLineArgument elipses to open the dialog that passes arguments to TFSBuild. You probably only see one variable listed:
MSBuildArguments
You can now add the current build reason to the command line arguments (and still pass any existing MSBuildArguments), similar to this:
String.Format("/p:CurrentBuildReason={0} {1}", currentBuildReason, MSBuildArguments)
Click OK to close the dialog. That will pass the current build reason as a new argument named CurrentBuildReason and it can be referenced as $(CurrentBuildReason) in your MSBuild scripts.
Save and check-in the Upgrade Template.
Assign the template to a Build Definition. The MSBuild scripts used by that definition can now use the variable as described above.

Related

Modify setting in web.config on TFS build

Is it possible to modify a web.config file in one of my projects during a Team Foundation Server build? Inside of my web.config file I have two setting keys: VersionNumber and BuildNumber.
Is it possible to change the value of BuildNumber based on the ID of the build in TFS?
Since you're using TFS 2013 you have an easier option than the old way of modifying the workflow - Use PowerShell.
If you're using the build template TfvcTemplate.12.xaml (which is the new default in TFS 2013), then you have some extra build definition parameters you can set to specify Powershell scripts to run. This way you just write a little bit of powershell code that gets the TFS Build Number (from an environment variable), then finds your web.config file(s) and changes them.
There is a sample script published in the TFS Community Build Extensions project that will do something very similar that you could modify. It finds all AssemblyInfo.cs files, then uses RegEx to modify them to update the build number based on the TFS Build number.
See the sample PS script here: https://tfsbuildextensions.codeplex.com/SourceControl/latest#Scripts/ApplyVersionToAssemblies.ps1
See some docs on how to modify the build to run PowerShell here: http://msdn.microsoft.com/en-us/library/dn376353.aspx
The answer is yes, though it's non-trivial. I've done this in the past using two methods.
Method 1: Use CodeActivities and alter the TFS Build workflow XAML file to include the new CodeActivity as a workflow step.
Here's an article on creating custom workflows with custom code activities (it's a little dated but still relevant):
http://blogs.msdn.com/b/jimlamb/archive/2010/02/12/how-to-create-a-custom-workflow-activity-for-tfs-build-2010.aspx
Basically, you create a new object that inherits from CodeActivity, create properties for your inputs (BuildNumber,VersionNumber, TargetFile), perform your actions on the TargetFile and save it. Then you wire up this new DLL with your activity to the TFS Workflow XAML, injecting your activity in the desired build step (post-build & pre-package in your case I bet to ensure xml transforms are applied).
Method 2:
Tag the desired properties onto the MSBuild invocation inside the TFS XAML file so they are passed in to MSBuild and available for your to use as $(BuildNumber) and $(VersionNumber). Then you can use MSBuild tasks to inject the properties into the file at the right time.

TFS SourcesDirectory is null/empty when used in Expression Editor

I have a build definition which has two working folders specified. One of these has the following columns:
Status: Active
Source Control Folder: $/MyCompany/MyDivision/Solution2
Build Agent Folder: $(SourceDir)\Solution2
I am trying to access this Build Agent Folder from within the Expression editor in TFS 2012?
I've tried SourcesDirectory but when it gets evaluated it is null/empty. Is there something specific I need to do to get SourcesDiretory to work in the expression editor? Or is there a better way to reference this specific build agent folder in it's entirety?
The SourcesDirectory and indeed the BinariesDirectory are not set till later in the build. They are not immediately available at the start of the build.

How do I use TFS to autobuild a non default configuration

We have a large code base with various labels which need autobuilding.
We are using TFS 2012 Express and VS 2010
Our code is build by a batch file so I have created a dummy solution which the autobuild builds, the build instructions for this solution just run the batch file.
I had the idea of using different configurations in this solution to build different labels.
So, as well as debug and release configurations I added one called LABEL which calls a different batch file and added a new automatic build in TFS which calls this solution with the 'label' configuration in the box Required - Configurations to build.
However, when I try to run it it fails claiming that the 'label' configuration does not exist.
Does anyone know how to do this?
Extra:
It seems to work if I use the Release configuration to call one batch file and the Debug one to call another but it still cannot find user created configurations?
If presume "Autobuild" means "build via TFS build definition".
If by "label" you mean a source control label, then when queuing a build, you can set its "Get Version" parameter to a label - for example, for the label MyLabel use LMyLabel.
If by "label" you mean some definition internal to the batch-file build, then you can pass it via an MSBuild property: Define it in the build definition by adding "/p:label=mylabel" to "MSBuild parameters". Then, where the solution calls your batch, you can use $(label) to get the value from the build definition.
Also, instead of this hacky .sln, you could modify the build template to call your batch file directly, and have a parameter which you set in the build definition, and the template passes it to the batch file.

Retrieving path to solution(s)?

We are currently setting up Team Build 2010 for our company, and I am trying to use workflow activities to retrieve the exact local path to the current solution being built. I haven't found a way to get this value, does anybody know how (without writing a custom activity)?
Either one of server or local path would suffice (i.e $/TeamProject/Branch/OurProject or C:\TeamBuild\src\path\to\branch\OurProject) since we can use the conversion activities on the server item.
The reason we need this path is for updating version info files, and that needs to be done for only the current solution being built, and the files have the same names (AssemblyInfo.cs, for example).
In this similar question, the solution is to define a parameter, but since this information is particular to the solution being built and not some external path, we were hoping that this info would retrievable.
You can retrieve this particular info without adding anything. If you navigate within your Build Process Template to the position where MSBuild breaks out, you will see that the solution that shall be build is set as a string named localProject. This will contain the local path where TFS has downloaded your SLN, something like C:\TeamBuild\src\path\to\branch\OurProject\OurProject.sln.Open the XAML and navigate to:
Run On Agent
Try Compile, Test, and Associate Changesets and Work Items
Compile, Test, and Associate Changesets and Work Items
Try Compile and Test
Compile and Test
For Each Configuration in BuildSettings.PlatformConfigurations
Compile and Test for Configuration
If BuildSettings.HasProjectsToBuild
For Each Project in BuildSettings.ProjectsToBuild
Try to Compile the Project
Compile the Project
Run MSBuild for Project
if you select Run MSBuild for Project & hit F4 you see it.
In order to retrieve what you are after you can define another string-variable solutionPath in your Build Process Template & insert under the Run MSBuild for Project a new Assign activity withTo : solutionPath andValue : Path.GetDirectoryName(localProject)
Have you looked at the TFS Community Build Extensions, they give you a assembly versioning out of the box?
You can use the variable called SourcesDirectory to get the current Source Directory on the Build Server. You can also use an ConvertWorkspaceItem activity to convert between server and local paths.
There's also a blog post that cover's all of this here.

How to make build definition in TFS Build 2010 configurable w.r.t input variable values and "items to build"

We are using TFS Build 2010 for Builds. We have two branches of source code (Lets say branchA and branchB).
Now as a part of the build definition we set the projects to build:
Now to employ the same build definition from branchB will mean that I create another build definition file with same content, with only the items to build set to "$/branchB"
Is there anyway to make this configurable, without having to edit the build definition?
Also there are other input variables that we set for the build definition, and the values for these variables are included in the build definition XAML file. So to change the value of a variable will mean that we have to edit the build definition XAML file. This is not desirable.
I would like to be able to set the "Items to Build" and the variables of the build definition without having to modify the build definition XAML file.
Are there any solutions to these problems?
You can modify the Build Process Template so it only asks you for the Items to Build. The rest of the arguments are prefilled. To get an idea how this works, see http://www.ewaldhofman.nl/?tag=/build+2010+customization
You can add parameters to your build definition. I did this a while back because we had two web projects in a solution that had to be deployed to different servers (via Windows shares). I added parameters to the build def so that in the build properties I could customize them depending on if it was a dev deployment, staging, etc.
I added a blog post on how to do it. You can use the parameters this way so that they aren't kept in the XAML file.
Deploying Web Apps with a customized Build Process in TFS

Resources