August 2005 - Posts

A custom Nant task for deployment

Finally.I got round to automatically deploying our web projects to our development server today in our build script. I thought that it was all going to be very easy. After all, Nant has lots of tasks, ready made to choose from.

When I came o have a look at it, I found that the standard copy task would probably not be suitable. After all, I don't want every file moving over to the dev server from the build server. So the next thing was to look into writing a custom Nant task.

Can I copy project?
First, I thought that I would try and use the EnvDte and VSLangProj references to build a programmatic CopyProject feature, like the one that is built into Visual Studio. This turned out to be pretty easy to code as I have done this before but the problem was that didn't have a version of VS.NET on the build server, just the SDK, and the CopyProject feature needs to create an instance of Visual Studio from its progId. Goodbye to that idea.

Bespoke Copy
In the end, I threw together a class, based on the Nant.Core tasks that would simply copy all files and folders recursively from the source to the target. I am also able to supply a list of files that I don't want to carry over. Something like this:

< copyproject source="C:\Inetpub\wwwroot\MyWebFolder" target="\\MyDevServer\share$\website\MyWebFolder" >
< excludefiles >
< fileextension name="VS Project Files" value=".csproj" />
< fileextension name="VSS Files" value=".vss" />
< excludefiles />
< copyproject />


This is great, but I'll be looking for a way to improve this. I had a bit of a look over the other Nant contrib tasks but couldn't immediately see anything that would be of use. Still, this only took a couple of hours to do and it all works pretty well. Build time is still small for a solution containing 22 projects with a complete deployment of 6 web projects to 2 web servers.

Cheers

R
with 7 Comments

No event handlers when linking from another virtual directory : solution

Strange. The problem is now fixed. To recap, I was basically getting loss of event handlers on an ASP.NET page when I was accessing the page via a link on another page in a seperate virtual directory. Link to the problem is: http://www.dotnetjunkies.com/WebLog/richardslade/archive/2005/08/24/132134.aspx. As this was our development server, I was able to look at the IIS Configuration. On the properties of the Project 2 virtual directory, this was using anonymous access. Integrated Windows Authentication was off. Checking this option made all the event handlers work. Turning it off again seemed to disable any button events. This could be consistantly replicated.
with 3 Comments

No event handlers when linking from another virtual directory

Have a bit of a problem. I'm sure that I will get it solved, but it is proving to be rather tricky. Perhaps there is something obvious that I have missed. After all, my bleary eyes were tired and crumpled from the days coding. Here is what is happening, what we have in place and how I replicate my strange situation.
 
We have 2 development web servers, load balanced with sticky concurrent sessions.
We have many web projects in one solution, but in this example problem I only need 2 projects.
Each project is published to both web servers
The web servers are both set up in the same way
Each of the two projects sits under a separate virtual directory (E.g. www.mysite.com/Project1  and www.mysite.com/Project1/Project2)
Project 1 uses NT Authentication and so does not allow anonymous access
Project 2 allows anonymous access

The problem
From www.mysite.com/Project1 there are a set of links. One of these links takes the users to www.mysite.com/Project1/Project2 . On the project 2 section, there are some buttons with normal .net event handlers behind them. If I navigate directly to www.mysite.com/Project1/Project2 then all works fine. However, if I navigate to www.mysite.com/Project1 , click on the link to project 2, then all of the buttons on project 2 have lost the event handlers. The buttons do nothing more than reload the page. Even more strangely, after I see that project 2 is not working, if I copy the url, close the browser and re-open it, pasting in the url that was not working (project2) then all works fine.
 
So, in the morning, I guess I'm just going to run a whole series of tests, and will hopefully be able to post how this was solved, and probably the silly thing that I haven't yet thought of. However, if someone else has ever seen anything like this, please feel free to share the love and let me know what on earth it could be. Solution to follow (one hopes)....

with 1 Comments

To unit test private methods, or just the publics

Hmm, I see that there is often debate about what should and shouldn't be tested with regard to unit tests.Many beleive that it is enough to test all the public methods of a system while others are sure that every method should be fully unit tested. This, for me at least is a tough one. There are, I think many factors to consider.

So, what are the factors involved? - Here are just three.

  1. Pressure from the business to write production ready code. Yesterday
  2. The difficulty in testing private methods
  3. Public methods are exposed interfaces, therefore if these are fully tested, why test what they call. 

It doesn't quite sit right with me that each part of the system isn't tested. After all, there is no more reason why the private methods shouldn't break than the public ones. Why should private methods suffer the loneliness of a test-free life. On the other hand, these are hidden chaps that are never exposed to our clients. All those proud public method chaps are sitting on the front line and happily calling the privates for help when needed.

Also, to test the private methods seems like it's going to add some overhead, certainly in time and resource. If our public methods are properly, no really properly tested then we would also be duplicating some of the testing, surely.

In my experience, there is always a balance to strike between doing the best possible to ensure that we write robust, maintainable and bug free software and resigning ourselves to the fact that it's the busness that pay our wages and if we can test what we expose well enough then we are saving ourselves time and overhead while still delivering on-time and within budget.

By now you should know which side ofthe fence I sit on. Test all your public interfaces, but do it well.

For those interested, here is a link to a good article on testing private methods in C# http://www.codeproject.com/csharp/TestNonPublicMembers.asp

Cheers

R

with 3 Comments

Configure your site to drop anywhere

I've often found that when I build a web app, I need a standard way of recalling certain pages/controls by the full URL.

I also don't want my pages littered with mappath statements. I need to be able to account for what happens when I drop my web application onto another server that has, for example, SSL certificates installed, or perhaps we need to put the application in a directory off the main site.

Well, I think that this way of acheiving this seems to be easy to configure and provides a standard means for any .NET site. Here's what I do...

A small web.config entry

Simply add the following line to the web.config file. This is the only thing that you may ever need to change when you place your site in a different server/folder.

A small method

Add this simple method to a class in your project

public string ProjectUrl()
{
string httpType = "http://";
string baseUrl = HttpContext.Current.Request.Url.Authority;
string projectFolder = ConfigurationSettings.AppSettings["projectfolder"];
if (HttpContext.Current.Request.IsSecureConnection)
{
httpType = "https://";
}
return httpType + baseUrl + projectFolder;
}

Using it

This can be used in all sorts of places. References in user controls, the global.asax for exmaple. If your web directory changes (when publishing from dev - production server for exmaple), just change the web.config entry. Https is already taken care of. Of couse, when you call the method you can just apend whatever page, image, etc.. that you would like on the end.

Cheers R
with 1 Comments

The need for a better build script

My build script is just too verbose. In fact, I am generally too verbose but that's another story. The other day I came to add a new project to my Nant build script and I realised what I had been putting off. My build script just isn't that great. Hey, I'm not saying it's awful but it could do with some tidying up.

When I put together our continuous integration server I was like a kid with a new toy, but quickly found how few examples there are of how to correctly write a really good build script and even more importantly, how long it seems to take to get a good one going.

Currently, my build script for my current project performs the following tasks, all quite simple:

  • Runs all unit tests -that depends on
  • Build each project - that depends on
  • Get latest version from scource safe - that depends on
  • Clean and make directories

The solution isn't huge, about 17 projects at the moment, but there are no settable properties in the build script and I need to change it if I want to build in release mode. It all works pretty well on a daily basis and each developer uses CCTRAY so everyone can see who breaks the build, and when (ok, it was my fault last time), BUT, it could be a lot better. I'd like to hear from people on experiences with Nant and Cruise Control.NET. It would be great to get some definative "this is the way to structure a build script" examples.

the next step will be to add more tasks to the build so it will automatically deploy to a staging server when each build passes.

Cheers

R

with 2 Comments