Friday, May 18, 2012

MSBuild-by-Convention

I've recently open sourced a set of build scripts  for .NET development on Github to assist you in automating compilation, running tests, creating release artifacts and deploying those artifacts:
https://github.com/JorritSalverda/msbuild-by-convention

In this article I describe how to use them on your workstation, in your Continuous Integration/Delivery server and what parts still need a bit more attention.

What are the goals?



  • To be able to set up a new project with as little effort as possible to avoid having any projects that live without CI, because of the lack of time to set it up. To reduce setup time the scripts favor convention over configuration.

  • To be able to run all actions equally well from your workstation as from the build server.

What does it automate for you?


The scripts are continuously improving, currently they do quite a lot:

Compilation

  • Versions all your compiled assemblies with parameter BuildVersion, which needs a major.minor.build.revision (1.5.13.859 for example) version number.

  • For both MVC and WebForms applications it compiles them using AspNetCompiler to check for errors in your views.

  • Outputs your generated assemblies to a set directory, so solutions can reference assemblies generated by another solution within the same repository.

Testing

  • Runs tests created with both NUnit and Machine.Specification.

  • Runs JMeter tests.

Creating release artifacts

  • Minifies CSS and Javascript grouped per directory with YUI Compressor and versions the filenames to avoid any caching issues after deploy.

  • Compiles Flash with Flex, outputs it to your web project and versions the filename.

  • Applies config transforms for any config file (where the original is called [a-z]+.config and the transform [a-z]+.[a-z]+.config).

  • Creates artifacts for each environment you have a config transform for.

  • Updates filenames with 1.0.0.0 in them to reflect the current build version to avoid caching issues and updates all references to them in css and js.

  • Precompiles asp.net websites.

  • Removes any files that shouldn't be part of the release.

  • Optimizes pngs.

  • Optimizes jpegs.

Deploying release artifacts

  • Deploys websites using MSDeploy.

  • Deploys database projects.

  • Deploys data-tier-applications (supported by Azure).

  • Deploys Azure packages to staging, then swaps to production and removing staging afterwards; which of these steps is executed can be parameterized.

Various

  • Delete Azure instances.

  • Analyze code using FXCop.

Which actions are taken for what projects is automatically handled by sticking to the project naming conventions. More about these below.

Read on to learn how the build files are structured, how to use them and how to configure them in your favorite CI server.

Wednesday, March 17, 2010

Maintainable MVC: Binding

This article is part of the Maintainable MVC Series.



By using the form models as spoken about in View Model and Form Model the need for custom binding doesn't arise to often anymore.



But every now and then we have some duplicate code doing something with incoming parameters. Perhaps we can move this logic into a binder to be more DRY. Or if our form model has types that MVC can't bind automatically - like enumerations - custom binding comes into play.



MVC is extensible on the part of binding form data or get parameters to your method parameters. You can define your own binders and have them work for certain types.


Wednesday, March 10, 2010

Maintainable MVC: Post-Redirect-Get pattern

This article is part of the Maintainable MVC Series.



It keeps amazing me that every time I see some example MVC code from Scott Guthrie, Phil Haack or one of our other MVC heroes, it keeps looking like this:



[csharp highlight="10"]
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Create(BlogItem blogItem)
{
if (ModelState.IsValid)
{
...
return RedirectToAction("OtherAction");
}

return View(blogItem);
}
[/csharp]

The big problem with this code is that it returns a view (on the highlighted line), while the method handles a POST. It seems like a very bad practice, because it disrupts the natural flow of your website. It makes it impossible to make use of your browser history (the back button) without running into a 'this page is expired' warning. Or your user could post the same data multiple times.



It is an annoyance which will definitely cost your website some visitors! So no more return View in a post method!