Tuesday, November 29, 2011

Fixing Stuck Builds in TFS 2010

Sometimes builds will get stuck in TFS 2010 and no build with a priority of "Normal" will build. You'll find that you have to change to priority to something higher in order to actually trigger the build. This usually happens because of an unhandled build failure on a build with "Normal" priority. TFS thinks there is another "Normal" build ahead in the queue, and therefore holds off on building your new request.

So how do you fix it? This requires going into the database. Open that database for the collection that is having the problem and look in the tbl_BuildQueue table. Check the Status column in this table. Anything with a "2" means it is still queued (and therefore blocking any new builds). Change these to a "16", which means "Cancelled". That should fix your problem!

Monday, November 21, 2011

Set Image as Wallpaper in Google Chrome

I love Google Chrome. It's my go-to browser, whether I'm on a Windows or a Mac OS X system. But there's one thing that annoys me about it: there's no way to set an image as a desktop background. IE does it. Firefox does it. Why doesn't Chrome? Well, because Google says that this is a rarely used feature and therefore they don't plan to ever support it. Google, you're wrong.

Fortunately, there's a simple workaround. Just go get the "Set Image as Background" Chrome extension. It's free and works great. When you right-click on an image, you simply get a new menu option that says "Set image as wallpaper". It's that easy. The only downside is that it only works on Windows, though I hear that Mac and Linux versions are in the works.

Tuesday, November 15, 2011

Branching in TFS 2010: Part V (Sharing Common Libraries)


In the previous four parts of this article (start with Part I here), I covered the theory behind branching and the three main patterns that use in our projects. The only detail to wrap up is how to share common library code between projects. We do this with a combination of build events and branching. Note that this method only works if both projects are in the same collection. You can't branch between two projects if they are in separate collections. So plan accordingly.


Sharing Common Code
In order to share common code, we need to take care of a few preliminaries first. The common library project needs to contain a "Deploy" folder that contains the final binary assembly. This assembly will be stored in the TFS source control repository. We'll make use of pre-build and post-build events to help automate the process of keeping this assembly up-to-date. Then, each End-User project will have a "Lib" folder. When a project needs a common assembly, we will branch from the "Deploy" folder of a particular release branch into the "Lib" folder of the referencing project. TFS keeps track of all this in the file history, so we can see who branched what assembly to what project and when. This is also handy when something needs to be rolled back.

This is how the folder structure looks for the common library, showing the "Deploy" folder:


Once the folder structure is set up, the build events need to be set up. Right-click on the project and choose "Properties". In the Properties window, select the "Build Events" tab. In the "Post-build event command line:" box, enter the following:
copy /Y "$(TargetPath)" "$(SolutionDir)Deploy"
It looks like this:


Make sure you have the "Deploy" folder created, and then build the solution once and make sure it copies the assembly correctly. If not, check your paths and make sure everything is in the right place. Once you get it built, create a solution folder in your solution, and add assembly into it. This will ensure that the assembly gets stored in TFS. Then check everything in.

Now at this point, if you try to build again it will fail because the assembly in the "Deploy" folder is read-only, since it's stored in TFS and checked in. One solution is to remember to check out the assembly each time before you build, but honestly....who wants to do that? Instead, we can automate that task, too.

For this, we're going to use a pre-build event. Into the "Pre-build event command line:" box, enter the following:

For 64-bit Windows, use:
"C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\tf.exe" checkout "$(SolutionDir)Deploy\$(TargetFileName)"

For 32-bit Windows, use:
"C:\Program Files\Microsoft Visual Studio 10.0\Common7\IDE\tf.exe" checkout "$(SolutionDir)Deploy\$(TargetFileName)"
It should look like this (this screenshot is from the 64-bit version):


This pre-build event will now check out the assembly from TFS before each build, which will allow the post-build event to copy over it after the build is done. It's still up to you to remember to check it in once you're finished.

This is all that's needed on the common library side of things. You do your releases as I've described in the previous parts of this article, and each release branch will then contain the "Deploy" folder with the binary assembly.

On the other side, make sure each project that needs a reference has a "Lib" folder in its solution and references all shared libraries from there. All that's left now is to get the assembly from the "Deploy" folder of the common library project to the "Lib" folder of the End-User project.

Note that you can put your "Lib" folder at the project level, or at the solution level. The choice is yours. Putting it at the solution level will keep you from having duplicate assemblies in each project's separate "Lib" folder. On the other hand, having a "Lib" folder per project gives you the added flexibility of allowing you to have a different version of the same assembly for each project. You need to decide which approach works best for your needs.

Once the "Lib" folder is set up, the only thing left is to branch a specific version of the common library into that "Lib" folder. Do that by right-clicking on the actual assembly (the .dll file) from the "Deploy" folder of a particular release, and branching it into the "Lib" folder of the other project.


Note below that the Source and Target are two different projects. This is the key to this type of sharing.


This method of sharing is superior to simply copying the assemblies manually as needed, because it allows tracking and rolling back of changes through TFS. The version history of the files will show what projects a specific assembly has been branched into, and what versions of various assemblies are included in a given project.

Here is a slideshow that contains the information in this article:
That concludes my overview of branching and sharing code in TFS. I hope it is useful, and feel free to leave feedback on how I can improve this, or future, articles.

Sunday, November 13, 2011

iCloud Photo Stream


Photo Stream is one of the many iCloud services available for iOS devices, as well as for Windows, Mac OS X, and even Apple TV. The idea behind Photo Stream is that pictures you take on any of your devices are shared, via iCloud, to all of your other devices. Simple, and useful, enough. However, here are seven things you may not know about iCloud Photo Stream:
  1. On iOS devices, photos are uploaded as soon as you leave the Camera app, as long as you are on wifi. Photos will not be uploaded over a cellular connection.
  2. Photos are only stored on iCloud for 30 days. Normally this is plenty of time for each of your devices to download the photo. But if this is a problem based on your usage patterns, make sure each device is connected to wifi at least once every 30 days.
  3. iOS devices are limited to the last 1000 photos in the Photo Stream. Mac and Windows systems will keep all photos, however.
  4. While Mac and Windows systems keep the native resolution of the photo, iOS devices may resize to photos to a resolution optimized for the specific device.
  5. Photo Stream does not support videos.
  6. Photo Stream photos do not count toward your iCloud storage limit.
  7. You cannot delete individual photos from the Photo Stream, only all of them at once. Doing so will not delete the photos from the individual devices.

Friday, November 11, 2011

11/11/11 11:11:11

It's 11/11/11 11:11:11...I know, it's geeky. But I had to post something!


Wednesday, November 9, 2011

Branching in TFS 2010: Part IV (Internal Pattern)

In Part III of this article, I discussed the End-User branching pattern and how to create it in TFS 2010. In this part, I'll be talking about the Internal pattern. The End-User pattern was a hybrid of the Branch by Quality pattern and the Branch by Feature pattern. The Internal pattern is also a hybrid of the same two patterns, but a somewhat different hybrid to meet the specific needs of the Internal projects.


Internal Projects

What we call Internal projects are those that are never directly used by customers. The most common example of an Internal project is a common library that is shared by multiple End-User projects. As a result, there can be multiple different versions of an Internal project in production at any given time. Another key difference between End-User and Internal projects is that Internal projects do not go through a formalized testing process like UAT. In some ways the Internal pattern is simpler than the End-User pattern, but in other ways it's more complex.

The Internal branching pattern looks like this (click for a larger view):


This pattern only has two main branches, Development and Bug Fix. Development is the main branch where all day-to-day coding occurs. Bug Fix is used for coding bug fixes to released code, and also as a staging ground for production releases.

The first step is to create the folder and branching structure. This is done just like in Part III, except for the obvious changes in the number of branches. It should look like this when done:



The branching hierarchy is quite simple, like this:

That completes the basic set up. There are four main processes that can happen during an Internal project:
  1. Development Cycle
  2. Major Release
  3. Incremental Release of the Latest Version (bug fix to the latest released version)
  4. Incremental Release of an Old Version (bug fix to an older released version)
The first part of this, the Development Cycle, is exactly the same as what I covered in Part III for the End- User pattern, so I won't go over that again.

The next part, a Major Release, is slightly different. It looks like this:

The biggest difference here compared to what we've done before is the presence of the label. The label comes in handy for making bug fixes to older releases, as we'll see in a little bit. To apply the label, right-click on the Bug Fix branch and choose "Apply Label...":


After that, give the label a meaningful name, like "Release 1.0":


Finally, create a read-only branch for the release, just like before. That's all there is to it for a Major Release.

An Incremental Release is similar, except the bug fix coding is done in the Bug Fix branch, and not in the Development branch. And just like with the Major Release, don't forget to label the code in the Bug Fix branch.


The only other thing left is an Incremental Release, and this is where we'll finally make use of the labels we've been creating. So far up to this point, we've released version 1.0 and a subsequent version 1.1, which contained a bug fix to 1.0. Let's say that now we have a bug in 1.0 that needs to be fixed, but we don't want that fix to be incorporated into 1.1. This is how you do it.


First, rollback the code in the Bug Fix branch to Label 1.0. Do this by right-clicking on the Bug Fix branch, and selecting "Rollback..."



Then make sure you choose the correct label in the correct project (by default Visual Studio searches labels in all projects, not just the current one).


Once this is done, all the code in the Bug Fix branch has been reset back to the Release 1.0 state. At this point, follow the same procedures as a  normal Incremental Release - make your bug fix code changes, test them, and release them into production as Release 1.0.1. Also, merge your changes back down to the Development branch if you want - this step is optional. Note that Development contains 1.1 (or possibly later, unreleased) code. If you want this bug fix incorporated into those version, merge your changes down to Development. For example, if you didn't want this bug fix in 1.1 for some reason, but do want it to appear in a future 2.0 release, go ahead and merge. If you don't, and this bug fix is solely intended for Release 1.0, then don't merge your changes down to Development.

The final step is to rollback the code in the Bug Fix branch (which currently contains 1.0.1) to 1.1. This will ensure that the Bug Fix branch is always left in the state containing the latest released code. Doing this will simplify future releases, both Major and Incremental.

That completes an overview of all the major tasks involved with Internal projects. In the next part, I'll finish up with explaining how to share these common Internal projects across multiple End-User projects.

Here's a slideshow that covers the information in this article:

iCloud Control Panel for Windows


I just downloaded the iCloud Control Panel for Windows. This is a nice little that lets you manage your iCloud account and check available storage space directly from a Windows computer. Note that after you install it, there is no program to run. Instead, it shows in your Windows Control Panel. It took me a few minutes to discover that!