Showing posts with label MSBuild. Show all posts
Showing posts with label MSBuild. Show all posts

Thursday, May 06, 2010

Configure WCF in IIS for anonymous access

This case may sound strange and I have seen loads of post that describes how to get out of this behavior. But we have a case where we want to allow anonymous access and the let a external component manage the security validation.

This turned out to be very hard to figure out and required some wizard-like skills of Anders Granåker amongst others.

OK – the case is very simple. I have a WCF Service that I want to allow anonymous access to. I don’t care about message and transport security (for now). Just allow anonymous access – I’ll take care of the authorization in code.

Here is what I had to do to get it to work on Windows 2003 R2:

  1. Create a account on the server
  2. Put that account into the IIS_WPG group
  3. Create a virtual directory for my WCF service
  4. Create an application in that virtual directory
  5. Set the account as Identity on the application pool that the virtual directory is using (DefaultAppPool for example)
  6. Set the account as the anonymous account the virtual directory is running under (Directory Security)
  7. IISReset to get the settings to take

The last step is a bit interesting… In this time and age you could think that a simple recycling of the application pool would be enough but … no. Do an IISReset to be sure.

Another gotcha that confused us a lot was that when you set an account to be the anonymous account for the virtual directory, you’re prompted to set the password. And retype it to be sure. But that password is not check if it’s the right password! Beware – I locked out our administrator account due to this.

Now it works – and we have a build script that is doing regressions tests via SOAPUI.

Wednesday, April 14, 2010

Calling SOAPUi Testscript from MSBuild

Yes, I know that I have written about this before, with several updates. But I have now solved some issues with setting different endpoints for different services and thought that I might need to update the MSBuild-script to be able to call with those parameters also.

Again – the script I am starting off is written by Todd of the Tar Pit. I’ve just tweaked it to take project property as input. That was the recommended way to change the endpoint for one service, to set the endpoint to a projectwide parameter.

So, here is what the new MSBuild targets looks like.

And here is a DOS-command that runs the MSBuild-target TestAll with the project property set to a endpoint.

Please note that I was running this on a 64-bit Windows 7 and got some strange paths (Framework64) that you want to change..

You can download my complete (now updated) project from here.

Wednesday, March 03, 2010

SOAPUi and MSBuild

After my last post I cannot withhold you from this nugget. It’s a guy (Todd) that have created some MSBuild targets to call SOAPUi from a build script.
I am about to try it out… I’ll get back to you if I run into problems.

[UPDATED]
Yup - it worked! Great! Thanks Todd.

Still have some issues in that the switch /endpoint will override all the endpoints in the SOAPUi project... But I'm on it...

[UPDATED AGAIN]

See this on how to solve the endpoint problem.

Friday, January 30, 2009

Create textfile on the fly in build scripts

Yesterday we did a final touch to our build script (by we I mean "I talked about it for five minutes, Christer did it").

We wanted to create a bat-file that installs our database in a certain version to a certain environment. So - the information we need to be able to do that is only know at runtime in the build-script.

From what I could remember there was a MSBuild community task for this - this was my input.

Christer then found the task WriteLinesToFile and wrote the following target that creates a bat-file as above.

<ItemGroup>
      <CmdLine Include = "@ECHO OFF"/>
      <CmdLine Include = "ECHO About to install version $(BuildVersion) on environment $(DeployEnv)"/>
      <CmdLine Include = "SET /p passw=Enter DB password for $(DeployEnv): " />
      <CmdLine Include = "CALL main.bat $(DeployEnv) . $(BuildVersion) %passw%"/>
      <CmdLine Include = "PAUSE"/>
    </ItemGroup>
    <WriteLinesToFile File="$(PublishWebSitePath)\Database\Installera_$(DeployEnv)_version_$(BuildVersion).bat"
Lines="@(CmdLine)"
Overwrite="true"/>

 

This version will wait for a password from the user so that the  password didn't need to be hard coded into the script.

Nice Christer - Nice!

Tuesday, January 20, 2009

Update AppSettings with XmlUpdate in build scripts

I know I will chase this one for ever if I don't put it up here...

We ran into a situation where we needed to tweak the AppSettings-section of an configuration before tests in the build script.

Luckily there is help to be found. With the XmlUpdate-task (in the MSBuild Community Tasks) this can be accomplished. IF you know how to write the XPath-query.

Here is how (found it here):

<XmlUpdate
   Namespace="http://schemas.microsoft.com/.NetConfiguration/v2.0"
   XmlFileName="$(SourceDir)\Core\ABSuite\ABClient\App.config"
   Xpath="//configuration/appSettings/add[@key='Main.ConnectionString']/@value"
   Value="$(DatabaseConnectionString)"
  />

Also here is a great site to pick up some XPath-skills.

Tuesday, December 09, 2008

Working directory for Build Agents and building different branches

We have been chasing a strange problem for a few days now. The scenario is as follows;

We created a new TFS build server, that is - we set up the build service on a new server. In our TFS Source control we had two branches with a build definition for each. Finally we set up a Build Agent for the new server via Visual Studio Team System.

But the builds failed! With error message "The path [path] is already mapped in workspace [workspace]"

We didn't get why until we checked a property on the build agent; Working Directory. This can be set by right-clicking on the Builds-folder in Team Explorer, choosing the agent and the Edit.

On the Build Agent Properties page there is a WorkingDirectory-textbox. This dictates where the agent should build. However - what not is shown is that you can use a variable in the path: $(BuildDefinitionPath).

Since our build script uses relative paths it was very important that the path looked the same in-different of the build definition. That is we wanted a separate build folder for each build. The $(BuildDefinitionPath) at the end of the WorkingDirectory-property of the build agent solved it!

Monday, December 08, 2008

MSBuild sidekicks

This tool, MSBuild Sidekick, looks quite promising. It's a graphical editor with which you build MSBuild project files.

I am always quite skeptical to tools when you "draw code" that you as easily can write. But this tools seems to hold some very useful features. I'll try to lab with it when I get the chance.

Wednesday, November 26, 2008

MSTest and secondary references

We've just solved a tricky thing in our project. We still don't get what is happening under the covers but now we've got it to work.

When we ran our unit tests (99% code coverage have I mentioned that :)) in the Visual Studio IDE everything was green and nice. However when the tests were run in our build script they failed with some strange reference problem. The same thing happened if we ran the test local via MSTest.exe.

OK - we then found the following post that showed us the same behavior. The solution is to in the .testrunconfig-file for the test configure DeploymentItems that points to any additional reference you need for your test to run.

Via the Test->Edit Test Run Configuration-menu item you can easily add files and folders.

Tuesday, November 18, 2008

Not trigger new build on check-in - TFS Build version of ExclusionFilters

OK - today we found out why we are building 650 builds each week...

As part of our build process we are checking out (and in) a version-file and a SolutionInfo-file. The problem however lies in that we have a build trigger that starts a build on each new check-in. So each build triggers a new build that triggers a build that ... you get the picture.

I have created build processes before with the great build server CruiseControl. In CruiseControl you have a configuration option that is called ExclusionFilter that solves this problem. You can tell CruiseControl not build trigger build from certain users/files.

This option is not around for us TFS Build users. But there are still a way around this. It's a bit of a hack and is described here.

The solution is to set a certain Check-In comment for your check-ins that shouldn't trigger a new build. The comment is even a MSBuild variable called $(NoCICheckinComment).

So here is a check-in that doesn't trigger a new build.

<Exec WorkingDirectory="$(CurrentSolutionRoot)" Command="$(TF) checkin /comment:&quot;New Version: $(Major).$(Minor).$(Build).$(Revision) $(NoCICheckinComment) &quot; /recursive Version.txt SolutionInfo.vb" />

Monday, November 17, 2008

XMLMassUpdate - how to keep environment in place with MSBuild

Another great finding in MSBuild for me recently is the use of the XMLMassUpdate task of MSBuild Community Tasks.

For quite some time now I have always kept a separate .config-file for each environment. Even though I always has gone "hmm... but wait a while here... 90% of this file hasn't changed from the last environment...".

But you don't get the time to investigate always. But now, again after some thoughtful input by colleagues, I noticed the XMLMassUpdate.

With it you can easily keep a file with the changes for each environment and then let your build script generate the right version for the environment the script is building. This means that you only need to keep the differences (deltas I think it's called in formal speak) of the different files. Great!

Here is an great article describing how to use the XMLMassUpdate-task.

I bet you can use this task to generate some code also if you want to... Just imagine to generate a project-file that includes some autogenerated classes, that compiles into... Brrr could be ugly or hard to handle. Not for me... Now.

Calling Sandcastle with response file

I've been generating documentation from our XML-comments with Sandcastle for quite some time now. It has worked alright but there were some stuff that really annoyed me, I though that I had to put up with it.
But this is the beauty of my line of work comes into play... all of a sudden we've got a new team member. Christer Cederborg from Avega (of course) - a great guy and very knowledgeable in things like build scripts and other. And you get to learn from each other. This is why I am in this business - sharing and knowing.
OK - Christer told me that you can use something called a response file to send commands to Sandcastle. The response file is in fact just the parameters you would send to Sandcastle the command line, but in a file. This made us go around the use of .shfb-files.
Sandcastle Help File Builder is certainly a great tool when you generate the documentation manually but is sucks when it comes to incorporating it into a build script. You cannot use wildcards or relative paths in .shfb-files which complicate things in a major way. I actually created two separate file, one for local developer use and one for our build script. They were of course almost always out of sync...
But with the use of a response file you can set all the commands you need to Sandcastle and get the same result. Here is a short extract from our response file:
-assembly=SystemName.*.dll, SystemName.*.xml
-dependency=Microsoft.Practices*
-dependency=System.Dependency*
-VisibleItems="InheritedMembers, InheritedFrameworkMembers, Protected, SealedProtected"
-ShowMissingParams=true
-ShowMissingRemarks=false
-ShowMissingReturns=true
And here is how to call Sandcastle in MsBuild with the use of the response file:
<PropertyGroup>
<!-- Sandcastle parameters -->
      <SandCastleExePath>C:\Program Files\EWSoftware\Sandcastle Help File Builder\SandcastleBuilderConsole.exe</SandCastleExePath>
        <SandCastleOuputLocation>$(DropLocation)\SystemDokumentation\Tjanster</SandCastleOuputLocation>
        <SandCastleWorkingDir>$(CurrentSolutionRoot)\SandCastleWorkingDir</SandCastleWorkingDir>
        <SandCastleResponseFile>$(CurrentSolutionRoot)\Solution Items\Documentation\SystemName.SandCastleSettings.txt</SandCastleResponseFile>
</PropertyGroup>

<Target Name="GenerateDocumentation" Condition="'$(Documentation)' == 'true'">
    <!-- Clean directories -->
    <RemoveDir Directories="$(SandCastleOuputLocation)" />
    <MakeDir Directories="$(SandCastleOuputLocation)" />
    <RemoveDir Directories="$(SandCastleWorkingDir)" />
    <MakeDir Directories="$(SandCastleWorkingDir)" />
    <!-- Create the documentation with call to Sandcastle with the parameters of the response-file -->
    <Exec WorkingDirectory="$(OutDir)"
Command="&quot;$(SandCastleExePath)&quot; @&quot;$(SandCastleResponseFile)&quot; -workingpath=&quot;$(SandCastleWorkingDir)&quot; -outputPath=&quot;$(SandCastleOuputLocation)&quot;" />
    <!-- Clean working directory -->
    <RemoveDir Directories="$(SandCastleWorkingDir)" />
</Target>

Tuesday, November 11, 2008

TFS Build targets and properties - the official list

For some time now people has been turning to me at my customer for answerers regarding TFS Build. I have learned a great deal from that but sometimes I feel like I haven't made sure that I understood the underlying thought from Microsoft.

One of those areas is that the TFSBuild.proj-file is not your ordinary MSBuild-file. Or rather; it's is but is run by Team Foundation Server and you get to configure it and it's properties. This is what I though and I was actually right. Phew!

There are some properties and targets that you can override in order to customize the build process. You can think of these targets like events being fired, and you can hook into them and customize their actions. And this is quite easy once you know how.

But then I often get the question; "Ok - what can I configure". I haven't had a good answer (this was my best so far) but now I found a list of the customable targets and properties.

Also I found out that any properties you define in the build script can be sent-in as a parameter. Either from the command-line (or textbox for command line arguments in the Visual Studio GUI) or via the .rsp-file.
If the already has a value that value will be overridden with the sent-in value. The value you set in the .proj-file can be though of like a default-value.

So - some good finding for a lazy Tuesday mooring in the couch. Abbe is sound asleep and I am doing MSBuild. Life is good.

Thursday, October 30, 2008

The right way of calling MSTest in a TFS build script

OK - sometimes it just to confess - I took a chance, or didn't know what I was doing - call it what you want.

In TFS Build-scripts there are a much nicer way of calling MSTest than the Exec-task as I suggested. There is already a task for it, called TestToolsTask. With this task you can much easier reach all the properties you need. And it even contains some undocumented features such as the TestContainer-property.

Here is my updated version on how to call the task:
<TestToolsTask   TestContainers="$(BinariesRoot)\Debug\Company.Service.Host.Test.Integration.dll"
          BuildFlavor="%(ConfigurationToBuild.FlavorToBuild)" 
          Platform="%(ConfigurationToBuild.PlatformToBuild)"
          PublishServer="$(TeamFoundationServerUrl)"
          PublishBuild="$(BuildNumber)"
          PathToResultsFilesRoot="$(TestResultsRoot)\..\IntegrationTestResults"
          TeamProject="Betalningsplattformen2"
          ContinueOnError="true" />

Wednesday, October 29, 2008

How to run MSTest with publish parameter as MSBuild Exec-task

[UPDATED, see this]

I have created a task that runs some unit tests in a certain DLL and the publish the result to a TFS service. We use this task in our TFS MSBuild script in order to execute some integration tests in the last step of the build process. In order to get some value from the integration tests the solution needs to be deployed, for example.

The most tricky parts of figuring this out was:

  • The path to MSTest.exe - as it turns out there are a environment variable to the root of the Visual Studio Tools - %VS90COMNTOOLS%. And via that we can reach MSTest.exe with %VS90COMNTOOLS%\..\IDE\MSTest.exe
  • To publish a build you need the buildId to send to the publishbuild-parameter of MSTest. It can easily be obtained from the TFSBuild parameter $(BuildNumber)

So here you are - my task to run tests and publish the results:

<!-- Run integrationtests -->
<Target Name="RunIntegrationTests" Condition="'$(DeployPT)' == 'true'">
<!-- Write nice message to log and in the build progress -->
<BuildStep TeamFoundationServerUrl="$(TeamFoundationServerUrl)"
BuildUri="$(BuildUri)"
Name="Integrationstester"
Message="$(PROMPT) Kör integrationstester mot den publicerade PT"
Status="Succeeded" />
<Message Text="$(PROMPT) Kör integrationstester mot den publicerade PT" />

<!-- Vi kör testerna med ett dos-kommando mot MSTest eftersom vi
vill köra det här i processen och inte i det normala test-flödet
för TFSBuild.
-->


<Exec Command="&quot;%VS90COMNTOOLS%\..\IDE\MSTest.exe&quot; /testcontainer:$(BinariesRoot)\Debug\Test.Integration.dll /publish:server.url /publishbuild:$(BuildNumber) /flavor:debug /platform:AnyCPU /teamproject:MyProject" ContinueOnError="false" />

</Target>

Thursday, October 23, 2008

ReSharper crashes

First and foremost- I love Resharper (4.0), but I think that some small flaws are still there and does bad things...

Two things are at the top of my list (in all honesty I must admit that I can't be 100% sure that ReSharper has to do with this but both of them has occurred after I've installed ReSharper):

  • ASPX-pages are very, very slow to load in design-mode. It can take about a minute to switch from the html-code to the design-view
  • The Build supervisor (you know, the view where you stare at the progress of the build, keep your fingers crossed and hopes for only green dots...) crashes very frequently.

I have reported these bugs to ReSharper and hope that a fix will be available to fix this. I still love Resharper though.

Oh yeah - that's right - I found that the TFS Web Access has some great view of the build progress in the browser, where Resharper cannot touch it. So I created a link there which works great:

http://[TSFWebAccessServer]/UI/Pages/Build/Explorer.aspx?pid=[yourProjectID]

Monday, October 20, 2008

MSBuild, refactor and targets in other files

I found a very niffty little feature of MSBuild, that is really helpful when it comes to structuring your build file.

In MSBuild the "sub-routines" are called targets and works just like expected, that is you can call the targets and invoke them in the order you like. BUT, there are no way of sending parameters to them - which at first are very hard to understand.

From this article I learned how to do it. And it's not to hard. But it's a bit of a hack... in my opinion.

Actually it's easier to describe it as it's intended from the outset, to call targets in other files. Imagine that you create a MSBuild-file called DeployScript.proj with a target called DeployIt. In order to deploy to different environments we use some variables that instructs MSBuild to deploy to different paths for example. Like the $(PublishWebSitePath) in the example below:

<RemoveDir Condition="Exists('$(PublishWebSitePath)')" Directories="$(PublishWebSitePath)" />
    <MakeDir Directories="$(PublishWebSitePath)" />

We can now call the targets of the DeployScript.proj-file from another file, with parameters, in the following manner:

<MSBuild Projects="DeployScript.proj" Targets="DeployIt" Properties="PublishWebSitePath=\\[server]\[share]" />

And now it's quite easy to understand how to call targets in your own MSBuild-file with parameters. It's works the same way as above. You just give the current build-file name in the projects-value.

Using this technique you'll get a much better way of structuring your build-files. And maybe even get some reusable stuff for your next project...

Thursday, August 07, 2008

Creating link to TFS Reports in build script

For a few days (on and off, not continously) I've been searching the net for some way to present code coverage data in a nice way. That is - when our build script is running tests under code coverage we don't present the code coverage result.

The code coverage data is located in the TRX-file generated by MSTest. And there is a great tool, trx2html, that I've already blogged about. But that tool doesn't show the any code coverage result.

Here I must add that I know these two things:
  • firstly the main part of the code coverage data is only interesting to the developers and might not benefit from being shown to others.
    But I just want to show that 97% of our code is covered by out unit test. Calms the project management...
  • secondly - it might be a simple thing to tweak the internal XML Transformation of the trx2html-tool.
    But it doesn't feel good to have tweaked third party code in a professional environment.

OK - after a long while I realized that TFS is, out of the box, giving us some reports. One of the is called Builds and simply shows a list of all builds, with code coverage data in place.

So I ran that report, which opens in the browser, and it did the trick; it shows the right amount of data at a reasonable level.

Now I just needed to create a link to the report and put it in the drop-folder for our build so that all persons interested could see the latest results. Here is what I did - not pretty, but it works;

  • I browsed to the report and dragged the link (the little icon in the url-field) to my desktop
  • I opened that "Internet shortcut" in Notepad and copied the entier content
  • Then I added a txt-file to my solution and pasted the content of the Internet shortcut into that file.
    For some reason you can't add a Internet shortcut to the solution.
  • Then I created a MSBuild target that copies the file to the drop location and change its file-extension to .url.
    Here is my target:

&lt;!-- Target that creates a link to the builds report -->
&lt;Target Name="SkapaLankTillByggRapporten">
&lt;BuildStep TeamFoundationServerUrl="$(TeamFoundationServerUrl)"
BuildUri="$(BuildUri)"
Name="CreateLinkFileToBuildReport"
Message="Create link to build report"
Status="Succeeded" />
&lt;Message Text="Create link to build report" />

&lt;Copy SourceFiles="$(SolutionRoot)\Solution Items\Tools\BuildReportLink.txt" DestinationFiles="\\$(DropServerName)\Drops\$(AppName)\TestResults\BuildReportLink.url" />
&lt;/Target>

  • Finally I made my build script call that target

As I said - maybe not a very pretty solution but it sure came through for us and helped us report code coverage data in a nice way.

Oops - almost forgot... To reconnect to the title of this post. This "technique" can of course be applied to any report in TFS or other URL-addressable resources.

Tuesday, April 29, 2008

How to fail a tfs-build on test failing

One thing that really surprised me was that when tests fail in my build script the build script happily ran along after that!? Isn't one of the ideas with Continuous Integration that the build script only will emit working versions?

Well in this article Aaron Hallberg (Swedish relatives?) shows us how to handle this. What he basically does is to check the status of the test-run and then update the status of the complete build.

I extended his code to use the test-status-flag on the tasks that follow the test, i.e. the publish task. This task deploys the executables to my test server, update the documentation etc.

So now I've got my desired result which is that failing test leads to failing the whole build.

Thursday, April 10, 2008

Sending parameters to msbuild in TFS

The build process in Team Foundation Server is the one part where you still miss some stuff. Although it is much better in TFS 2008 than in TFS 2005 it is still quite cumbersome to handle.

The way you start off with a wizard and then almost always need to go into the .proj-file to do updates is also confusing. Most people don't want to be fiddling around with the nitty-gritty details of a MSBuild-script - it is not pretty.

These, and other reasons, has led many of the projects that i am involved in to create a lot of build scripts - and some of them is not need. Like, for example, you shouldn't be needing a separate build script to deploy to a certain environment, or the deploy part should not have to get and rebuild the sources.

The solution to this is of course to send and handle parameter in your build script. This post is a short introduction to how to do this.

Parameters in MSBuild-scripts
A MSBuild-script can be started without the assistance of the TFS, of course. For example on the commandline (msbuild.exe). And besides the actual .proj-file the msbuild-enginge is going to run through you can send a lot (and i mean a lot) of switches and stuff.

One of them is /p which is a list of parameters (separated by commas) that the script can act on. The parameter becomes a standard property in the build script. So if the build script is started like this:

msbuild.exe /p:Marcus=12 build.proj

it can be reached in the build script like this:

<Message Text="Marcus has the value:$(Marcus)" />
<Target Name="CreateDocumentationWhichTakesALongTime" Condition="$(Marcus)=='12'">


Parameters to TFS Builds
But how do you get parameters send to the build script that is run inside TFS?

Well if you are running TFS 2008 you can send additional parameters in the dialog for Queueing new builds - the textbox is called MSBuild command-line arguments (duh!). In this box you give your arguments with the /p-switch;

/p:Marcus=12

If you want a certain parameter to go with the build script each and every time you build you can do so via the .rsp-file that is located in the same folder as the build, in Source Control. Here you can add your own custom parameters but also some standard parameters. More on this can be found here.

Thursday, March 20, 2008

Publish TFS testresult as HTML

OK - this is one of thoose "now where has that file moved"-posting.

When you run tests in a TFS build with MSTest a .trx-file is created. This file contains all the testresults for that run. However you can't view it unless you have Visual Studio...

(Appearently you could publish the result to the Team Foundation Server and then do a report but this is much simpler...)

Here is a tool, trx2html, that converts that .trx-file into a nice HTML-report. And that report could then easily be published on the Team Portal.

And here are, based on this article, some steps on how to include the functionality in your build script:

  1. Download the tool

  2. Include the RidoTask.dll in your solution or reachable on the server where the tests are run. I've included the dll in a solution folder in my solution, called SolutionItems\Tools

  3. Reference the msbuild task in your build file (.proj)
    <usingtask assemblyfile="$(SolutionRoot)\SolutionItems\Tools\RidoTasks.dll" taskname="RidoTasks.trx2html">

  4. Convert the trx into html after TFS has dropped the results
    <target name="AfterDropBuild">
    <calltarget targets="CreateTRXReports">
    </target>


    <target name="CreateTRXReports">
    <createitem include="$(DropLocation)\$(BuildNumber)\TestResults\*.trx">
    <output itemname="trxfiles" taskparameter="Include">
    </createitem>
    <ridotasks.trx2html filename="%(trxfiles.Identity)">
    </target>

  5. Inform your project where to find your latest reports, which is the same directory as the testresult itself

    <Exec Command="xcopy "$(DropLocation)\$(BuildNumber)\TestResults\*.htm" "$(TestResultReportPath)" /Q /H /R /Y" />

That's an easy way to keep everyone informed