TFS 2008: Build agent configuration options
While some of the build agent properties are available in the VS GUI, buried in the tfsbuildservice.exe.config file are a number of options that control key aspects of the build agent and the build. This file existed in TFS 2005, but it had fewer options. While you don’t have to change anything for the build agent to work in the normal case, there are options here that will help you get more out of the product. In future releases, these types of options will be exposed in better ways (e.g., GUI).
Everything described below applies to TFS 2008 Beta 2 through TFS 2008 RTM. Many of these settings were also in Beta 1, for those of you that are experimenting with that release (if the setting doesn’t appear in the tfsbuildservice.exe.config on your build computer, then it was added after Beta 1). Some of these features were described earlier but with much less detail.
Any time you make a change to the tfsbuildservice.exe.config file, you must restart the Visual Studio Team Foundation Build service (from the Windows Start menu, choose Run and execute services.msc, select the service and click Restart).
Building independent projects simultaneously
The msbuild included with the .NET Framework version 3.5 has the capability of using multiple processes to build projects in your solution that are independent of one another. In TFS Build, the default is to continue to use only one process for maximum backwards compatibility. To make use of this new feature, you’ll want to set the MaxProcesses setting to a different number. One general rule of thumb is to set it to twice the number of processors or cores in your computer. Finding the optimum value, though, will require experimentation with your own builds since that depends on the I/O and CPU characteristics of your builds. Aaron wrote about this recently.
Running GUI tests as part of your builds
A Windows service doesn’t have access to a desktop, and thus the standard configuration of the build agent cannot run unit tests that involve GUIs. You can do that, however, if you log onto the build computer as the user account that you want running your builds and simply run tfsbuildservice.exe from a Visual Studio 2008 Command Prompt. Leave the logon session up, and tfsbuildservice will run indefinitely. We call this running the build agent “interactively” for lack of a better term. In the config file below, you will find the InteractivePort setting. That port number, which defaults to 9192, is used by the interactive build agent. When you configure the build agent in the Visual Studio GUI, simply change the default port of 9191 in the Build Agent Properties dialog to be 9192 instead. Now you can run GUI tests as part of your build!
See How to: Configure an Interactive Port for Team Foundation Build for the steps.
Requiring an authenticated user connection to the build agent
In TFS 2005, the communication between the TFS application tier (AT) and the build agent used .NET Remoting. With the advent of Windows Communication Foundation (WCF) in .NET Framework version 3.0, we were able to change to using SOAP web services like the rest of TFS without requiring that IIS be installed on the build agent. In TFS 2008, we default to requiring that every connection to the build agent is authenticated via NTLM, which is the AuthenticationScheme setting. However, it could still be any valid Windows account. To further secure your build agent, you can now also specify the service account under which that TFS AT is running as the only user allowed to connect to the build agent. That setting is the AuthorizedUser.
Using HTTPS, possibly with X.509 certificates
TFS 2008 supports X.509 certificates. As part of that work, we added the capability to use HTTPS to secure the web service communication channel between the application tier and the build agent. To require that HTTPS be used to connect to the build agent, simply set the RequireSecureChannel setting to true. You will also need to set the checkbox in the Build Agent Properties dialog for the build agent in Visual Studio (Build -> Manage Build Agents, then choose Edit to modify an existing agent or New to create a new one). Additionally, you can require that the communication to the build agent use X.509 certificates by setting RequireClientCertificate to true.
We’ve still got a ways to go to provide true extranet or internet support, but we’ve made some improvements in this area. When the TFS AT calls the build agent, it sends the build agent its URL. That URL comes from the AT’s web.config file. It’s value is set when the TFS AT was installed. It typically uses the short name of the server. For example, it’s typically http://mytfsserver:8080 rather than http://mytfsserver.somedomain.corp.company.com:8080. If your build agent needs to contact that server using either that fully qualified domain domain (FQDN) or perhaps an entirely alternate name, such as http://secretserver.extranet.company.com:7070, you can set the ServerAccessUrl setting to be that other URL. The AllowedTeamServer setting must still match the URL sent by the AT, so it would typically hold the short form.
The AllowedTeamServer setting exists also in TFS 2005, but you’ve likely never seen or even heard of it unless you need to change which TFS AT the build agent will listen to. That’s because that when that key is not set, the URL of the first AT that successfully communicates with the build agent is stored in the registry (HKCU for the account under which the build agent is running). Its role and behavior has not changed in TFS 2008.
At the risk of getting lost in minutia, I want to explain one more related aspect. Feel free to skip this part if it’s not clear. To determine whether the AT that is connecting to the build agent is the correct (allowed) server, the build agent will compare the value in AllowedTeamServer or the HKCU registry (.config file setting has precedence) to the server URL sent by the AT. If the two match, it continues processing the request. If they do not match, the build agent tries to determine if it’s really the right AT but with a different name. To do that, it requests the GUID from both the server specified by the URL that was sent with the request and the server specified by its configured server URL. If the two match, it continues. If they don’t, it will reject the request. In TFS 2005, the build agent would call the domain name server (DNS) to get the IP addresses to do the comparison. The change to using each server’s GUID is an incremental improvement that will help folks who’ve had problems with this in the past.
Oh, and don’t forget that if your build agent is separated from you TFS AT via a low-bandwidth connection, you can set the build agent to use the version control proxy.
Possible support for future versions of msbuild
While we don’t know what the future of msbuild holds, we do know that the TFS 2005 build agent cannot run the new msbuild in .NET Framework 3.5 because the code gets the CLR runtime directory to determine the location of msbuild.exe. Those who’ve paid close attention to the difference between the CLR and the framework will know that the CLR version in Visual Studio 2008 remains 2.0, while the framework is obviously 3.5. The result is that the TFS 2005 build agent will only execute the 2.0 version of msbuild. To attempt to be a bit more future proof (no guarantees, of course), we’ve included a setting that allows you to specify the path to msbuild.exe. This means that if the .NET Framework 4.0, for example, contains a new version of msbuild (3.0, by the way, did not), you would be able to specify the path in the MSBuildPath setting to have the TFS 2008 build agent use it. There’s no way to know for sure at this point whether it would work, of course, but at least you’ll have the option.
Separate log files per project
Have you ever wanted to have a separate build log file per project? Well, we know some of you do, because it’s come up on the MSDN Build Automation forum a number of times. If you set LogFilePerProject to true, you will get that.
Better support for source files with really long paths
A number of users ran into problems in the TFS 2005 build agent where they had trouble building their applications because the paths to the source files were really long. The TFS 2005 build agent would create a build directory path that consisted of the build directory set via the GUI dialog or the tfsbuild.proj file, the team project name, the build type name, and then the word “Sources.” The result was that users were left with substantially less than the Window’s path limit of 260 characters to work with (yes, Windows supports 32K character paths, but .NET doesn’t).
In TFS 2008, you have options to deal with this. Aaron provides the details here. The short version is that you can set the root of the build directory in the Build Agent Properties dialog. If it’s still not short enough, you can use the SourcesSubdirectory setting to shorten the word “Sources” to “s” if you want. So you can end up with something as short as C:\b\s, if you need.
We’ve provided a number of new options for the build agent in TFS 2008. While it’s far from ideal that you need to edit a .config file and restart the Windows service for the changes to take effect, we’ve at least gotten support in there to address some of these issues. In future releases, we’ll be working to make these and other options easier to work with.
I’ve copied the contents of %ProgramFiles%\Microsoft Visual Studio 9.0\Common7\IDE\PrivateAssemblies\tfsbuildservice.exe.config below for reference (minus the tracing information at the top of the file). As you can see, we tried to document the settings to make it easier to know how to change them. Hopefully, there’s enough here to get you going.
<?xml version=”1.0″ encoding=”utf-8″ ?> <configuration> <appSettings><!– port This is the port that is used by the Team Foundation Server Application Tier to connect to agents hosted by this executable when it is run as a windows service. This value has to be the same as the value specified for the agent(s) in the Application Tier. –> <add key=“port” value=“9191” /><!– InteractivePort This is the port that is used by the Team Foundation Server Application Tier to connect to agents hosted by this executable when it is run as a command-line application. This value has to be the same as the value specified for the agent(s) in the Application Tier. –> <add key=“InteractivePort” value=“9192” /><!– AuthenticationScheme This string controls what type of authentication will be accepted for incoming connections. The following values are supported: Anonymous, Digest, Negotiate, Ntlm When specifying Negotiate, the Build Service Account must satisfy one of the following conditions in order for Kerberos authentication to work: – If on a workgroup, it must be NT AUTHORITY\Local Service – If on a domain, it must be NT AUTHORITY\Network Service or the account must have a valid SPN The Basic authentication scheme is not supported. –> <add key=“AuthenticationScheme” value=“Ntlm” /><!– AuthorizedUser This key provides a mechanism to restrict all access to the agent service to a single account. If this value is set then a transport authentication scheme of Basic, Digest, Negotiate, or Ntlm must be used. –>
<add key=“AuthorizedUser” value=“” /><!– RequireSecureChannel This boolean value controls whether or not transport-layer security should be used for the exposed service. Normally, HTTP is used for communications which may not be desirable for a machine exposed on the internet. Set this value to true to expose the service using HTTPS instead. This value has to be the same as the value specified for the agent(s) in the Application Tier. –>
<add key=“RequireSecureChannel” value=“false” /><!– RequireClientCertificate This boolean controls whether or not a client certificate should be required when using a secure channel. –>
<add key=“RequireClientCertificate” value=“false” /><!– AllowedTeamServer This is the Team Foundation Server Application Tier that can connect to this build machine. This value should be the URL for the AT, such as http://myserver:8080>. This value overrides the setting in HKCU. –>
<add key=“AllowedTeamServer” value=“” /><!– ServerAccessUrl This only needs to be set when the URL required to communicate to the Team Foundation Server Application Tier (AT) is different than the one specified in AllowedTeamServer. The most common case would be when the AT and the build agent are separated by the internet. For example, AllowedTeamServer may need to be <http://myserver:8080>, but the build agent may need to use http://boundaryserver.corp.company.com:80> to connect to the AT. –>
<add key=“ServerAccessUrl” value=“” /><!– BuildOnFatPartitions As a part of the build process, access controls are set on the build directory to secure it against unauthorized access. By default, only NTFS partitions are allowed as FAT partitions do not support access controls. To override this and allow building on FAT partitions set this value to true. –>
<add key=“BuildOnFatPartitions” value=“false” /><!– DoNotDownloadBuildType Set this flag to true if you want to use the build type definition existing on the local machine instead of downloading the definition from the server. The local path used will be the same as the location where the build type would have been downloaded. –>
<add key=“DoNotDownloadBuildType” value=“false” /><!– MSBuildPath Set this value to the full path to the directory of MSBuild.exe to use a location other than the default. This should only be needed if a new version of the .NET Framework is installed. –>
<add key=“MSBuildPath” value=“” /><!– MaxProcesses Set this value to the maximum number of processes MSBuild.exe should use for builds started by agents hosted by this executable. –>
<add key=“MaxProcesses” value=“1” /><!– LogFilePerProject Set this value to true if you would like Team Build to generate errors and warning log files for each project, rather than just for each platform configuration combination. –>
<add key=“LogFilePerProject” value=“false” /><!– SourcesSubdirectory Set this value to the desired sources subdirectory for the build agents hosted by this executable. –>
<add key=“SourcesSubdirectory” value=“Sources” /><!– BinariesSubdirectory Set this value to the desired binaries subdirectory for the build agents hosted by this executable. –>
<add key=“BinariesSubdirectory” value=“Binaries” /><!– TestResultsSubdirectory Set this value to the desired test results subdirectory for the build agents hosted by this executable. –>
<add key=“TestResultsSubdirectory” value=“TestResults” /></appSettings> </configuration>
[UPDATE 9/07/07] I’ve added a link to the official doc for changing the port.