Tuesday, August 23, 2011

Configure TFS2010 to enable Continuous Integration (CI) – How to Build and deploy a WCF service application?

Many development teams have adopted "agile" methodologies to manage change and to improve software quality. These methodologies promote continuous integration as a practice to build and test software products incrementally as new features are included, bugs are fixed, and code is refactored. Hence time to market is reduced.
Continuous Integration
Continuous integration is a simple, powerful technique that Martin Fowler promoted as a best practice in software development, and a technique that fits easily into an agile development process (see Continuous Integration). Continuous integration takes the notion of a daily build a step further by building a software product each time any unit of the software changes. In most cases, a build is created each time a developer checks any code or configuration change into a source control.  

My Build Environment
The situation is such that I was running a CI system with Visual Source Safe (VSS2008), CruiseControl.NET, FxCop, MsBuild, and in some projects with NAnt also. Then our onshore team decided to replace VSS2008 with TFS 2010. We managed migrate all source code as first step to TFS and decided not to touch existing CI process to keep migration simple. We just installed VSTS plugin for CrusieControl.NET from CodePlex, and wired up TFS2010 in CCnet.config projects. So far so good, TFS 2010 is smoothly working with CruiseControl.NET. Buts wait, it’s not the final goal, and we want to eliminate Cruise Control from CI process so that TFS2010 work using power of MSBuild and Team Build Service.
We thought about advantages/disadvantage of using TFS Build, topology should we prefer and security needs etc. After all we will utilize the power of TFS2010.
As first step, I will deploy a WCF service on remote machine say TARGETPC.  My TFS2010 is installed on Remote machine placed in Europe say TFSPC.
  1. Download and install the Microsoft Web Deployment Tool (or the 32bit equivalent) on the deployment machine TARGETPC (where the WCF service will ultimately be deployed).
  2. Create the IIS Web Site on the deployment server. Create a virtual directory (if needed) under website, and website should be started.
  3. Create a TFS Build Agent on the TFS server (See MSDN article Create and Work with Build Agents for details)
Visual Steps of Creating a new Build:

 Specify a workspace to get latest TFS code in Build Agent Folder specified (on TFSPC).

Select Clean Workspace = None so that only the files that are changed are uploaded to your IIS instance when we deploy. Copy Outputs to Drop Folder should set to false because don’t need a drop folder, so turn that off under Build Defaults by unchecking the box as well. I am using Agile methodology, so the Default Template will serve the purpose,
MSBuild Arguments are as follows:

/p:DeployOnBuild=True /p:DeployTarget=MsDeployPublish /p:MSDeployServiceURL=http://<RemoteServerIP> /p:DeployIISAppPath="<RemoteIISAppPath>" /p:CreatePackageOnPublish=False /p:MsDeployPublishMethod=RemoteAgent /p:AllowUntrustedCertificate=True /p:UserName=<yourusername> /p:Password=<yourpassword>

Here is parameter description:
1.    <RemoteServerIP> a simple IP address of TARGETPC machine on which “Web deployment agent service” should be installed.
2.      RemoteIISAppPath : I defined a new web site and a virtual directory in it. Because My virtual directory run under specific AppPool so I configure it once. So I specified following value precisely: "AutDist_Websites/Autodist.Server.CI.Deployment"
3.      User name and password of user having built rights in TFS server

When I use option “Queue New Build” I got following error message:

(3588): Web deployment task failed.(Remote agent could not be contacted.  Make sure the remote agent service is installed and started on the target computer.) The requested resource does not exist, or the requested URL is incorrect. Error details: Remote agent could not be contacted.  Make sure the remote agent service is installed and started on the target computer. An unsupported response was received. The response header 'MSDeploy.Response' was '' but 'v1' was expected. The remote server returned an error: (404) Not Found.

 Solution is as follows: The Web Deployment Tool does not install the Remote Agent Service by default. And I forgot to select the option in installation Wizard. If the Remote Agent Service is not configured correctly, the deployment activities outlined later in this past will result in an error message “The response header ‘MSDeploy.Response’ was” but ‘v1′ was expected”.
Steps to solve the problem are: go to Add/Remove program, rerun setup “Web Deployment Tool” and select option “Remote Agent Service”.

Now I can see the service entry under control manager.  The Web Deployment Agent Service is configured to start manually by default. It is necessary to reconfigure this to start automatically.

After starting the service I can see I can access following URL. Although display nothing but it asks for user credentials on Target machine.
Now on trying again I get following error:
Web deployment task failed. An error occurred when the request was processed on the remote computer.) An error occurred when the request was processed on the remote computer. Application 'ROOT' does not exist in site 'Automated.AutodistServer'.

Problem is I was providing virtual directory path directly and process was expecting is as IIS Website that it could not find. So I fixed it by creating a separate website and a virtual directory under it. RemoteIISAppPath = “Website Name\Virtual Dir Name”.
Now I retried queue new build and it is compiled smoothly, providing each build result, and finally WCF is deployed in target IIS Virtual directory. Cool, is not it. 
In future, I have to find out the ways to perform
- Code Analysis and Report merging
- Code Coverage and Unit Tests
- Merge Reports (needed?)
- Configure Emails to specific Team Members