Like me, you may have to do demos as part of your job. One of the things I demo often is TFS. Lately, I’ve been tapping into the powers of Team Foundation Server 2010 Basic. With the Basic edition, I can install real TFS on my laptop BUT I don’t have to install SharePoint (MOSS or WSS) or SQL Server Reporting Services. On top of that, I can implement it with SQL Server Express. I don’t have to run Windows Server. I don’t have to do this through a VM like VPC or boot to VHD. I can run it right on my laptop. And, with the Basic edition, I get source control, work items AND automated build. It’s truly an awesome thing.
The problem with pre-2010 TFS is that all my demo projects were mingled in with my “real” projects and it became a little bit of a mess especially when demoing. Keeping all the projects straight wasn’t a huge thing but still a bit of a pain. Now we have project collections and it’s easy to separate real from demo. There’s always a gotcha though and it starts with the way TFS is architected. A project collection is associated with a single build controller and that controller is associated with a Windows Service. You’re not supposed to have more than one controller/service per machine whether the controller is on the app tier or on a build machine. Here’s the problem: I can only set up builds for one of my collections.
There is a solution. Keep in mind though, it’s considered a hack and something you should NOT do on any kind of production system (because it’s completely non-supported) but it does seem to work. I found the solution as posted by Jim Lamb but my experience was a little different so I decided to post what I did with screen shots. So, here goes.
The solution is to manually install another build service and register another build controller to the 2nd collection – with the new build controller, you can create new build agents.
Here is the order of how I set up my machine before I realized the build issue:
- Installed TFS Basic
- Created the “DefaultCollection” as part of the install. That name can be anything you want but as I was a little short on creativity at the time, I used it.
- Created a couple Team Projects for some applications that I was working on (at this point I didn’t create any builds – I wasn’t to that point yet in the code)
- Realized that I had a couple demos coming up so I decided to take advantage of the collections feature and created a “Demos” collection
- Created a couple builds for the new demo projects assigning the build controller and created multiple build agents
- Did my demos of the automated build process (which all worked just fine)
- Went back to my “real” projects and wanted to create builds for them but realized the situation
In a nutshell, here’s the steps to create a new build controller:
- Install/Create another Windows Service which is a host for the build process
- Register the new build service and configure properties
- Create a new build controller and configure properties
There’s a few more actual steps involved but after that you can create agents to fire up the build definitions. Here’s the actual steps:
1) Install/Create another Windows Service which is a host for the build process and works directly with the build controller (1:1 relationship)
a. Open a command prompt window (must be opened “As Administrator”)
b. Call the “Service Control Manager” command line API to setup another Windows Service which will host the new build controller. The call format is: sc.exe create ServiceName binpath= “C:\Program Files\Microsoft Team Foundation Server 2010\Tools\TfsBuildServiceHost.exe /NamedInstance:InstanceName” DisplayName= “Name that appears in the services list display” Note: the spaces after binpath= and DisplayName= are required. This will set up another windows service instance that another build controller can be associated with. Naming suggestion is to include the collection name so you can easily see which service is assigned to which collection. Here’s the example of what I did:
2) Register the new build service and configure properties
a) The Team Foundation Administration Console can use the Windows environment variable “TFSBUILDSERVICEHOST” to identify the service that it should be administering and in the next step you need to start up the console and make it work with the right service. You do this in two steps. First, you just set the environment variable in the command window already open by typing this:
set TFSBUILDSERVICEHOST=InstanceName
where InstanceName is the name you gave your instance in the SC.exe command…hit enter.
b) Then, in the same command console window, you call up the TFS Administration Console with the command: “%programfiles%\Microsoft team foundation server 2010\tools\tfsmgmt.exe” (include the quotes)
If you get the following error message,
then you either didn’t create the service (SC.exe command) or your instance name/service instance names don’t match
c) The TFS Admin console will appear and will be working with the new service
In Jim Lamb’s post he mentions looking at the registry setting: “HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\10.0\TeamFoundation\Build\tfsbuildservicehost1” to verify a unique URI but in my RTM install that key did not exist so I went on to the next step.
d) Click Register and this window will appear:
e) Click “Browse” under “Communications” to assign the right collection to the build controller
f) Identify the TFS server, select the collection and click “Connect”
g) Now, you need to make sure that you are communicating on a port number that is different that your current one. The default build port is 9191 so I just made mine 9192
h) You can change the service credentials if you wish but then click “Start” to get the service/controller running
3) Create a new build controller and configure properties
a) Click “New Controller”
b) There is nothing you have to add at this point but you can add a description if you wish, limit the number of concurrent builds this controller will initiate, and finally, you can identify a location in source control where you can store assemblies that the build workflow may need to use (i.e., custom activities). Click “OK” and the controller will start up
That’s it as far as creating a new controller. Now all you have to do is create the build agent(s). You do this as you did before. There are some things to keep in mind though:
- When identifying the working directory for the new controller/agent make sure it is different than the original controller/agent otherwise there is a possibility of a conflict when builds occur. Just appending a description on the end of the build agent ID (e.g.: $(BuildAgentId)_CollName) or an additional subfolder (e.g.: “$(SystemDrive)\Builds\$(BuildAgentId)\CollName\$(BuildDefinitionPath)”) should be more than sufficient.
- Along the same lines, make sure the drop folders are different. This shouldn’t be an issue unless you name two projects the same but it’s still a possibility.
- If upgrades or patches are to be made to the system, remember that you have more than the original number of services active and if you need to quiet the services for that patch, there’s an additional service out there.
- Running multiple, simultaneous builds could cause performance issues. Just something to keep in mind.
Oh, yeah, when you need to use the TFS Admin Console and you go to “Build Configuration”, it may not be pointing at the collection/controller that you want to work with. To launch an admin console specifically for the collection/controller you want do the following:
- Launch a command window as administrator. If you don’t run “as admin” then the TFS console will probably not let you define the collection you want to work with.
- Set the environment variable TFSBUILDSERVICEHOST to the name of the service (like you did above in step 2.a.)
- Call up the Admin console with: “%programfiles%\Microsoft team foundation server 2010\tools\tfsmgmt.exe”
- Console should now be running against the right service and controller.
I just created a .bat file with those commands to make things easier. Again, launch it “as administrator”.
Again, this is a hack and not supported. Since doing this modification (several weeks now) I have not had any issues. I can do builds in both collections so it is definitely working on my machine
. Have fun building.