July 2006 - Posts
Although this post is a little dated, I was going through my email and noticed this as one of many things I meant to post but got delayed. Giovanni Gallucci captured my presentation at the Dallas Code Camp in June and posted it here... http://www.mediaswamp.com/blogs/agencycast/archive/2006/06/28/269.aspx
In case your interested, the MP3 audio should be sufficient as I used almost nothing in terms of slides and, although it wasn't my intent, showed almost no demos. It was a VSTS overview followed by heavily participant driven discussion. It was my first presentation in that format and I think it went pretty well. I haven't reviewed the audio myself yet so I can't speak to the quality, but Giovanni tends to do a pretty good job. Enjoy!
One of the many elements of Visual Studio Team System that is so appealing is the build system. Using the generic build wizard and scripts that it creates, Team Build provides an engine that can get your project from Team Foundation Version Control (TFVC), compile your Visual Studio solutions in your selected configuraitons, execute your unit tests, perform static code analysis, manage work item and changeset associations, and generate a multitude of outstanding reports.
And this wizard based system works great if your working with .NET 2.0 projects developed and built with Visual Studio Team System tools. If you're working outside of the sweet spot, perhaps working with .NET 1.1 or VB6, hitting a version control system other than TFVC, performing automated deployment of your applications, automating database deployment or other more advanced topics, Team Build can do it! But not without a little work.
Team Build is based upon the MSBuild engine which means you can extend it to do almost anything. Multiple community-based extensions have been created to do everything from manipulating IIS to changing file system attributes. And if you don't find the community extensions that you need, writing you own build tasks is relatively simple.
That said, even though developing advanced Team Build scripts can be fairly easy, it can also be rather time consuming. Many of the mundane portions of the build script can take significant time. If your build script pulls down large complex solutions that take awhile to simply fetch and compile your solutions. In my current project, I am translating a PERL-based build script that packages compact framework and interacts with Borland StarTeam to retrieve external assemblies. As such, most of the interesting things that I am working on happen after the all of the standard build stuff is complete.. and that process takes roughly 8 minutes when I am building both release and debug binaries. Thus, modifying scripts and custom build tasks and then testing is a slow and tedious process. Although I like my coffee breaks, consistently waiting for the mundane portion of the build is very inefficient. So let me point you to several properties that can be specified for Team Build which will skip some of the mundane portions of the build:
- SkipClean
- SkipGet
- SkipLabel
- SkipInitializeWorkspace
- SkipPostBuild
- SkipWorkItemCreation
You can probably guess what they mean so I won't bore you with details. But I will point out how easy it is to skip the portions of the script that aren't actively being used while you develop. In my case, most of what I am currently working on takes place after the build; hence, I can skip clean through initialize workspace by simply overriding these properties. This can either be done in a property group in your .proj or .targets files, or by overriding them from the MSBuild response file. Following is what my TFSBuild.rsp file contains when I'm debugging portions late in my build scripts:
# This is a response file for MSBuild # Add custom MSBuild command line options in this file /p:SkipClean=true;SkipGet=true;SkipLabel=true;SkipInitializeWorkspace=true;SkipWorkItemCreation=true /v:diag |
The /v:diag enables diagnostic-level verbosity in the logging. Although it results in extremely large build log files, they are very useful when developing and troubleshooting complex build scipts. Remember that once you've completed the script, your should delete these settings - or at least comment them out with a preceding #.
Note that skipping the clean through workspace targets doesn't skip the compile, but since the compile should already have up-to-date binaries from the last build before setting "Skip*" to true, the compile should be a very short step.
A quick word of warning... When you use TFSBuild.rsp to override these or any other propeties, remember that you've done so. Although that may seem obvious, when you're deep into development and debug in your .Proj and .targets files, it is easy to forget that the .rsp is part of the equation and equally easy to miss the obvious when trying to troubleshoot how your properies are getting set in the script. (Yes, this is from experience [:S]).
One typical scenario is the need to have an administrator (development lead, etc.) release the locks that a team member has placed on a file in the version control system. This frequently occurs when a user has to make modifications to a locked file, and the peron who locked the file isn't available to unlock it. Team Foundation Version Control does support this capability, but is isn't complete obvious. Here are the details...
The first step is making sure that you have the appropriate permissions. The permissions are managed using the Source Control Explorer. Each folder and file can be set to allow users or groups specific permissions, including: Unlock other user's changes and Undo other user's changes. A user that is granted these permissions can perform the unlock or undo as described below. By default, only the Project Administrators and Team Foundation Server Administrator groups have these permissions.
To actually perform the unlock or undo, you have to use the TF command from a Visual Studio command prompt. It is somewhat unfortunate that these capabilities aren't available from Team Explorer or Source Control Explorer, but this is hopefully an infrequent enough administrative task that it doesn't cause too many issues.
The specific commands for unlock and undo are as follows:
TF LOCK filespec /LOCK:NONE /WORKSPACE:workspace;lock_user
TF UNDO filespec /WORKSPACE:workspace;checkout_user
The important things to realize about these commands are as follows:
-
Filespec will most frequently be a path to a file or folder in Team Foundation Vesion Control (TFVC). For example: "$/MyTeamProject/MyFolder/Foo.cs". If you have embedded spaces in the path, make sure to use quotes around the filespec.
-
Filespec can can be a local file (e.g., "C:\MyTeamProject\MyFolder\Foo.cs") only if that local path is in the workspace holding the lock or having the file checked out. That means that it will have to be on the workstation of the user holding the lock/checkout. You shouldn't need the workspace switch in this case, but I haven't actually verified this personally.
-
If TF can't detemine the server, you're also need a server switch on the command line (e.g., "/server:mytfs").
-
You can add the "/recursive" switch to unlock or undo all changes for a specific user recursively under a folder in TFVC.
-
The workspace can be queried by looking at the properties of the item in Source Control Explorer and switching to the Status tab. It can also be queried using the TF command line utility.
-
The lock_user and checkout_user refer to the login for the user holding the lock or checkout. For example: "notion\dmckinstry".
The examples above would look like this if you wanted to unlock the file "Foo.cs" from my "DaveWorkspace" workspace:
TF LOCK C:\MyTeamProject\MyFolder\Foo.cs /LOCK:NONE
/WORKSPACE:DaveWorkspace;notion\dmckinstry
In theory, this same basic approach can be used to check in changes made by other users, but the note above pertaining to being in that user's workspace on their workstation would defintely apply.
As a consultant specializing in Visual Studio Team System, I spend a significant amount of my time customizing and extending Visual Studio and Team Foundation Server. Just as most people develop applications in a development environment before deploying to a production environment, I do my TFS development in a lab environment and only push to a client's server after the work is mostly complete. I work with many difference clients and tend to need different lab environments for each.
Which brings us to one of my favorite technologies for this purpose but also one to watch out for... Microsoft Virtual PC. Regardless of which virtualization technology you prefer, creating a virtual machine to act as your lab TFS makes perfect sense. In my case, I have several variations of the same TFS virtual image that I run depending upon which client or project I'm supporting. As long as I only have one copy booted at a time, everything works great, except for...
Visual Studio and Team Explorer provide a caching mechanism which can get out of sync. If I have multiple instances of a single TFS which can be connected to from a single Visual Studio client, that client can become confused. Symptoms vary, but I've had what appears to be connectivity or security issues but were actually related to trying to use cached data from one TFS instance against a different instance. Some of the problems were more esoteric but equally confusing, including phantoms in work item definitions or TFVS.
Although there are probably other ways to help, the simplest way that I've found is to delete the cache for the TFS on the client machine. The cache is kept in two subdirectories, named based on a server GUID, under:
C:\Documents and Settings\{your account}\Local Settings\Application Data\Microsoft\Team Foundation\1.0\Cache
Although I connect to many different TFS servers, I know the GUID for my favorite lab TFS server. Whenever I need to switch between VPC instances of that server, I clear the cache by shutting down Visual Studio, deleteing directories {Server GUID} and {Server GUID}_http from the aforementioned directory, and then restarting Visual Studio.
In many cases things looked like they were working fine without clearing the cache, but not that I know how this caching mechanism works, I always clear it when I move between different instances of the same TFS - just in case.
I just completed some work with a client, helping them understand how to model and manage their change management and build processes. Although the specific promotion modeling, etc, is ripe for a different posting, right now I'd like to return to the basics of Team Foundation Version Control (TFVC).
If you're using TFVC, you're probably already familiar with the term "changeset." You likely know that a changeset represents a group of versioned files along with associated meta data such as policy information, timestamps, comments, and the like. What you may not understand is that the 'versioned files' are actually understood by TFVC as the changes between version.
This is a fairly big deal. If you need to selectively merge changes, changesets provide the ability to do just that. Consider the following three file versions...
| (Baseline version) |
(Changeset A) |
(Changeset B) |
|
... public void method1() { // placeholder }
public void method2() { // placeholder } ... |
public void method1() { // Code added // etc. }
public void method2() { // placeholder } |
public void method1() { // Code added // etc. }
public void method2() { // Different code // added } |
It is probably easy to understand that if I have a branch based on the baseline version and merge Changeset A that the results will be the same as the file listed in changeset A. What causes some people confusion is that when I start with the baseline and merge only Changeset B, I get a result that is neither A nor B. Instead I get the base line with only the changes from A to B applied. The results look more like this:
| (Baseline with Changeset B applied) |
public void method1() { // placeholder }
public void method2() { // Different code // added } |
This is great if what you need is the ability to manage changes pushed between environments. You still have the ability to merge up to a given version. That is if I had merged to version Changeset B instead of just merging the selected changeset B, I would have ended up with the changes for both A and B.
I've sidesteps questions such as merge conflicts and a suite of other discussions. But this understanding by itself can make a big impact to how you plan and manage changes in your TFS source control systems.
A quick hint for people who plan to use TFS for version control but can't migrate their web projects off of ASP.NET 1.1 and Visual Studio 2003 just yet: the Solution User Options file, which is typically hidden and ignored, contains some valuable mapping information for version control.
If you used the MSSCCI provider under Visual Studio .NET 2003, this initial configuration and binding the solution to the new source control can be somewhat painful. I've scripted the process but at the various clients and projects I've worked with, the process doesn't seem fully reproducable. Instead of a script, here are some things to try as you go through it.
- Get Ready.
- When changing back and forth between VSS and Team Foundation Version Control (TFVC), close VS .NET 2003 and adjust the registry to modify your source control provider as necessary.
- I've had the most success opening the solution from source control and letting VS 2003 create the virtual directory, etc, from scratch.
- Note that when opening from source control for the first time, it may take a long time to open the solution. VS 2003 and the MSSCCI provider don't seem to give a status bar indiciating that it is working. Be very patient and it should return eventually.
- Once you have the binding fixed and everything checked in to TFVC, share your SUO. The time opening from source control or even the necessity to open into a virgin environment from source control seem to go away if you have an SUO file that already understands the TFVC worksapces, source control binding and IIS settings. This will help keep your co-workers from going gray as fast as you are from this process :).
More Posts