TFS/MSBuild caveats

Once again I am a bit off track from MOM. I've been digging more into Team Foundation Server lately. Unfortunately I've been negatively surprised how many obvious things just do not work as expected out of the box. Fortunately with many overrides, working with a friend of mine - Lukasz, and Aaron(https://blogs.msdn.com/aaronhallberg) I managed to get everything I needed working. The list is simple, but was not that easy to get running:

1. Build - Output of solutions to separate folders

That seems sooo obvious, but built-in TFS puts all binaries from all solutions you specify in a build into one folder.... Oh my.. It took us nearly 2hours to figure out why the build was failing (it was simply overriding release binaries, since two solutions had some of the outputs the same).

Here is the resolution. Use this file (add it to your build folder): alipkaAssemblyInfoUpdateAndOutDir.

In TFSBuild.proj add:

<Import Project="$(MSBuildProjectDirectory)\alipkaAssemblyInfoUpdateAndOutDir.targets" />

Then add this clause below the solutions:

<SolutionToBuild Include="$(SolutionRoot)\Source\solution.sln" >
<OutDir>mysolution</OutDir>
</SolutionToBuild>

This is much nicer design then in Manish post: https://blogs.msdn.com/manishagarwal/archive/2006/03/24/559693.aspx.

Kudos to Aaron for helping me out on this one. BTW he mentioned that 'Orcas' will make most of these things way easier... well, I hope.

2. Add assembly signing

I used a better approach then Gautam's:https://blogs.msdn.com/gautamg/archive/2006/01/04/509146.aspx.

Use the above linked targets file (alipkaAssemblyInfoUpdateAndOutDir). Then specify:

<SolutionToBuild Include="$(SolutionRoot)\Source\solution.sln >
<Properties>SignAssembly=true;AssemblyOriginatorKeyFile=C:\Keys\mykeypair.snk</Properties>
<OutDir>mysolution</OutDir>
</SolutionToBuild>

NOTE: if you are using Enterprise Library (like I am) you will need to recompile it with your own key to get it working (EntLib docs describe it well)

3. Add automatic assembly versioning

For that I used the approach from Gautam: https://blogs.msdn.com/gautamg/archive/2006/01/04/509146.aspx. But I modified it to get it working with points 1 and 2. Just import the targets file I linked above (alipkaAssemblyInfoUpdateAndOutDir) and provide the code as in Gautam's post in your TFSBuild.proj

NOTE: you won't be able to use default YYMMDD notation, because the unsigned INT overflows:( I went for modifying the default to MMDD notation. See: https://blogs.msdn.com/msbuild/archive/2007/01/03/fixing-invalid-version-number-problems-with-the-assemblyinfotask.aspx

4. Build - building installer projects

This unfortunately does not work in MSBuild. I used this approach: https://blogs.msdn.com/anutthara/archive/2006/01/05/509606.aspx. The downside: you need VS on your TFS build server.

5. Automatic deployment

I decided to use scripts with PSEXEC. And boom I hit a strange issue - it just seemed to time out. Apparently there are some buffer issues with that. Lukasz dug out an old WMI script for remote process launching from ITForum. I attach it for reference: RunProgram.

I copy installers to destination servers and then run them with the above program. I remove installers by providing the product codes as GUIDs:

Copy:

net use \\server\c$\dir Password /USER:Admin

copy C:\dir\APP.msi \\server\c$\dir

net use * /delete /y

Run:

cscript D:\Scripts\RunProgram.vbs "msiexec /x GUID /quiet" /computer:COMPUTER /username:ADMIN /password:PASS

(to install run: msiexec /i C:\APP.MSI /quiet).

SUMMARY:

Well that is a long list isn't it? And just to perform some basic tasks... Well lets hope it is only because this is a V1 product, and V2 will fix these issues.

Last thing. For more debug-level output from TFS builds use: https://blogs.msdn.com/manishagarwal/archive/2005/08/04/447583.aspx