Saturday, December 25, 2010

Continuous Integration Step 2 – FxCop Integration with MsBuild

An FxCop project specifies the set of assemblies to be analyzed, the rules used to analyze the assemblies, and the most recent analysis results reported by FxCop.
Local Path of FxCopCmd.exe on my build server is for example:
C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\FxCopCmd.exe
Challenge is to write a custom target for code analysis, plug that target in build process to perform analysis as last task and then produce the report in xml file.  So below the After Build target in previous post, I wrote following script:
  <PropertyGroup>
    <BuildDependsOn>
      $(BuildDependsOn);
      Bash_CodeAnalysis
    </BuildDependsOn>
  </PropertyGroup>
   
  <Target Name="Bash_CodeAnalysis">
      <Message Text ="Static Code Analysis Starts Here"  Importance="high"> </Message>
  </Target>

Build and verify that message appear at the end of “After Build” target execution. The code above is very simple that is, run Bash_CodeAnaysis target after standard build. Now I can write Exec Command afterwards.

<Target Name="Bash_CodeAnalysis">
      <Message Text ="Static Code Analysis Starts Here"  Importance="high"> </Message>
  
   <Exec Command="&quot;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\FxCopCmd.exe&quot; /searchgac /rule:&quot;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\Rules&quot; /file:$(ProjectDir)bin /out:C:\fxCop.xml" 
          ContinueOnError="true">
    </Exec>
</Target>

Note: Prefer to write Command value in single line otherwise command line tool will consider it separate commands and throws an error.
Parameters details that are passed in:
/searchgac – Tells FxCop to search the gac for any referenced dll's not found in say the bin folder.  If you forget this FxCop will error out.
/rule:Rull.dll – You can specify as many rules as you like to check against your compiled dll just repeat this command with each of the Rules you like.  Unless you have a specific FxCop project you must specify at least one rule. You can specify Rules folder as well
Note: As we are calling it from an MsBuild file which is XML we have to encode the quotes as “&quot;” otherwise famous 9009 error will be encountered.
/file:YourCompiled.dll – Much like the rule parameter you can specify as many .dll’s as you would like to check but need at least one. I specified project’s bin folder means all dlls to be analyzed in it.
/out:someXml.xml – You are going to want to specify an XML file to output the results to so that you can integrate the results in your build log.   CruiseControl.net uses XSL to transform the generated XML into HTML for viewing in its Web Dashboard and auto generated Emails.
ContinueOnError – Unless you have written your own FxCop rules you are most likely going to want to set this value to true so that your build doesn’t fail each time you break one of the many rules that FxCop specifies.

Here is another example analyzing single NamingRules.dll on single dlls only.
<Target Name="FxCop" DependsOnTargets="BuildProject> 
<Exec Command="&quot;C:\Program Files\Microsoft FxCop 1.36\FxCopCmd.exe&quot;
 /searchgac /rule:&quot;C:\Program Files\Microsoft FxCop 1.36\Rules\NamingRules.dll&quot;
 /file:C:\Project\bin\My.Framework.dll /out:fxCop.xml" ContinueOnError="true">
    </Exec>
</Target>

Now save the project file.
Open VS2010 command line tool again and browse to the folder where csproj file exists. Execute  this command:
 >>> MSbuild GD.AutoDist.MainService.csproj /fl
After build, static code analysis is performed by FxCop as follows.


Now next is to dig into CCNet  configurations :)
Provide your comments

Wednesday, December 22, 2010

Continuous Integration Step 1 – MsBuild Integration


How to start a Continuous Integration process is a difficult task. When things are up and running with Automated Process, it seems very helpful and easy to maintain. With minimal human interaction you can reduce your build time and accuracy and hence time to market the application. A great advantage.
There are a large set of options and combination of tools. We prepared a dedicated Build server machine in the company (TEO). Here is a set of software components on Build Server, I will discuss about each component’s wiring later on (decision about set of chosen package is based on our defined criteria including wide acceptance, open source availability and our needs).

MsBuild Integration with csproj file:
Our target is command line building of CSharp project  using MSBuild. I created an asp.net website in VS2010 and want to configure it to execute from command line tool. One goal is to copy the build files to root drive destination folder (also configured in metadata dynamically). So I unloaded the project file in VS and right clicked to go to “Edit project file”.  It opens the project file for editing.

At the end of file we can find ‘Before Build’ and ‘After Build’ commented targets. In the after build target we will write custom code.


Here is my code snippet instead:

  <!--MSBuild integration started here by Bash 20-Dec-2010-->

  <Target Name="AfterBuild">
    <Message Text ="Custom After Build Action Started" Importance="high"></Message>
    <ItemGroup>
      <ProjectFolder Include="$(ProjectDir)\*.*"                    Exclude="$(ProjectDir)\*.cs;$(ProjectDir)\*.csproj;$(ProjectDir)\*.user" >
        <!--Only imediate file of project folder-->
        <PublishTo>2010_MSBuild</PublishTo>
      </ProjectFolder>

      <BinFolder Include="$(ProjectDir)bin\**\*.*" Exclude="*.cs">
        <!--All files and sub folders in bin-->
        <BinFolderTo>2010_MSBuild/bin</BinFolderTo>
      </BinFolder>

      <AccountFolder Include="$(ProjectDir)Account\**\*.*" Exclude="$(ProjectDir)Account\**\*.cs" >
        <!--All files and sub folders in Account-->
        <AccountFolderTo>2010_MSBuild/Account</AccountFolderTo>
      </AccountFolder>

      <ScriptsFolder Include="$(ProjectDir)Scripts\**\*.*">
        <!--All files and sub folders in Scripts-->
        <ScriptsFolderTo>2010_MSBuild/Scripts</ScriptsFolderTo>
      </ScriptsFolder>

      <StylesFolder Include="$(ProjectDir)Styles\**\*.*">
        <!--All files and sub folders in Styles-->
        <StylesFolderTo>2010_MSBuild/Styles</StylesFolderTo>
      </StylesFolder>
    </ItemGroup>

    <Message Text="ProjectFolder :@(ProjectFolder)" Importance="high"/>

    <Copy SourceFiles="@(ProjectFolder)"  DestinationFiles="@(ProjectFolder->'%(RootDir)%(PublishTo)\%(Filename)%(Extension)')" />
    <Copy SourceFiles="@(BinFolder)"  DestinationFiles="@(BinFolder->'%(RootDir)%(BinFolderTo)\%(Filename)%(Extension)')" />
    <Copy SourceFiles="@(AccountFolder)"  DestinationFiles="@(AccountFolder->'%(RootDir)%(AccountFolderTo)\%(Filename)%(Extension)')" />
    <Copy SourceFiles="@(ScriptsFolder)"  DestinationFiles="@(ScriptsFolder->'%(RootDir)%(ScriptsFolderTo)\%(Filename)%(Extension)')" />
    <Copy SourceFiles="@(StylesFolder)"  DestinationFiles="@(StylesFolder->'%(RootDir)%(StylesFolderTo)\%(Filename)%(Extension)')" />

  </Target>

Now save the project file.
Open VS2010 command line tool and browse to the folder where csproj file exists. Execute  this command:
 >>> MSbuild GD.AutoDist.MainService.csproj /p:Configuration=Release
1.       MsBuild – Standard command
2.       Cs project file to be built
3.       /p is parameter with key-value pair; key= configuration and value=release
After build, the files will copy to root’s 2010_MSBuild folder.

Now next target is to analyze the code by Static Code Analysis. FxCop is the goal for integration. 

Sunday, December 19, 2010

Step 0 - How to start Continuous Integration Process

Continuous Integration
 (continued in futuer Posts)
Continuous Integration is the practice of integrating early and often, so as to avoid the pitfalls of "integration hell". The ultimate goal is to reduce timely rework and thus reduce cost and time to market an application.
How to start process in Organization
It was started with an idea that company should get maximum benefit from Continuous Integration. But very first challenge is how to start it? There are a number of tools and each with different capabilities and scripting code need to understand. On other hand it was a challenge that company run verity of .NET languages, with almost all flavors of .NET frameworks and all type of applications from small projects to long term maintenance projects. It could be enterprise applications, web-based, windows/form-based and network applications etc. We are using verity of source code repositories like TFS, VSS, some use SOS because their code ownership is on client premises. Some use VPN connection to do remote coding and does not interact with our local network. DMZs and further considerations etc.
Our lead then decided to develop a plan for this project. A road map to define the milestones at each level.

-          Define Mission Statement
-          Define Tasks
§  Value Addition
§   Success Criteria
The Process
We wanted to create a simple running process that is
-          Should not involve extra cost to company (should be mostly open source  or in place already in the company)
-          Should be easy to  adapt to various teams in the company
-          Should have minimum effort involve to pluggin the process in existing projects and new coming projects (Avoid unnecessary scripting, coding and configurations)
-          Should use well tested and stable set of tools so that running maintenance cost of process should be less.
-          Should perform less customization, until its necessary and first focus on start a process.
-          Once up and running in place, then enhance gradually by adding more areas/tools etc.
Execution Plan
Defined tasks and their breakdown
Start Survey across Organization
We started survey across the organization. Purpose was to collect necessary information to define the feasibility criteria, tools selection and maturing the process.


(To be continued ...)

Wednesday, December 15, 2010

WCF Hosting – Issues with VS2010 and Fresh IIS 6

I need to deploy a WCF web service to test environment. Web service is developed with VS2010 (.Net 4.0). When I prepared a build of 28 projects with single service using them. I just compiled and build the service with option ‘Any CPU’ and copy to test machine.

Test machine is Windows 2003 server x64 bit using IIS6. When I registered wcf service I figured out the ASP.Net is not registered with IIS.

Action: I run command >> aspnet_regiis –i
Next error appeared in browser was The Error 404 “Page not found” …..

On enquiry, I found that I should check the detailed sub option from log under 404. So I get to IIS->Web Sites->Propertie -> Log Properties and traced log file path. Then I opened log file where following last entry was there:

2010-12-14 04:03:30 W3SVC1 127.0.0.1 GET /GD.AutoDist.MainService/AutomatedService.svc – 80 – 127.0.0.1 Mozilla/4.0+(compatible;+MSIE+7.0;+Windows+NT+5.2;+WOW64;+Trident/4.0;+.NET+CLR+2.0.50727;+.NET+CLR+3.0.4506.2152;+
.NET+CLR+3.5.30729;+.NET4.0C;+.NET4.0E) 404 2 1260

What is 404.2. Here is a description:

404 – Page not found.

  • 404.0 – (None) – File or directory not found. ·
  • 404.1 – Web site not accessible on the requested port.
  • 404.2 – Web service extension lockdown policy prevents this request. ·
  • 404.3 – MIME map policy prevents this request.

So my issue is “Web service extension lockdown policy prevents this request.”. means my policy is preventing the ASP.NET 4.0 ISAPI extension from processing your request. It happened because check it out:


Starting from “0″ the last line means v4.0 aspnet_isapi.dll is disabled? There’s your problem. So to enable it I tried it:


Now when I tried to access WCF service I get following Error:

The type ‘xxxxxxxxx’ provided as the Service attribute value in the ServiceHost directive, or provided in the configuration element system.serviceModel/serviceHostingEnvironment/serviceActivations could not be found.
And here is Exception details:

System.InvalidOperationException: The type ‘GD.AutoDist.MainService.AutomatedService’, provided as the Service attribute value in the ServiceHost directive, or provided in the configuration element system.serviceModel/serviceHostingEnvironment/serviceActivations could not be found.
I googled the issue and found perhaps its good idea to add following line under services tab in web.config:

<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled=”true” />
….

Next error was as follows:

Server Error in ‘/’ Application.
Parser Error Message: It is an error to use a section registered as allowDefinition=’MachineToApplication’ beyond application level. This error can be caused by a virtual directory not being configured as an application in IIS.

Till now here is my IIS virtual directory settings: (Above error is saying I should create it as application)



When I created Application by clicking create button above, afterwards I get a new error:

Server Error in '/GD.AutoDist.MainService.AutomatedService' Application.
Could not load file or assembly 'GD.AutoDist.Server.Common' or one of its dependencies. An attempt was made to load a program with an incorrect format.
To enable assembly bind failure logging, set the registry value [HKLM\Software\Microsoft\Fusion!EnableLog] (DWORD) to 1.


I did above thing in registry and now I can see the error log in detail on webpage. But other than that what does this means: one of the dll ‘GD.AutoDist.Server.Common’ in my solution is creating a problem. But what’s it. I rechecked the bin folder and common dll lonag with all its dependencies was there. Then I realized, its 64 bit operating system, why not to check the build option for common library in VS2010. And I figured out that its x86 instead of ‘Any CPU’. So I changed it rebuilt the dlls and placed in deployment folder. (I also ensured that all the dlls are using Framework 4.0) Finally the issues are over. Now I can start wcf service in browser



That’s it:)