Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NAnt MVC publish website

Problem: I want to elegantly publish an MVC website with NAnt.

Simple no? Wrong... Here are some of the stackoverflow resources I've looked at. Each one of them has an issue...

Stackoverflow 1: Publish WebApplication using NAnt

The result of this one was that the web.config was not being transformed and additional files were showing up in the bin that weren't suppose to like the entity.dll.config of all things!

Stackoverflow 2: Replicate VS2008 "Publish Web Site" from command line

This one will do the same as the previous solution except it's even worse... it will copy EVERYTHING from my project and dump it into the publish folder... no joke!

Stackoverflow 3: MSBuild Script and VS2010 publish apply Web.config Transform

The accepted solution builds on top of Stackoverflow 1, but is pure MsBuild xml and not NAnt xml. It also only fixes the Webconfig and so still leaves those random files that show up. There is also another solution (not accepted) that pattersonc gives, which is very, very close to correct but the connection strings in the web.config are in a bogus limbo state, leaving you with yet another bad web.config

Needless to say it's been 3-4 days, 10+ different StackOverFlow answers and no silver bullet... Is there no easy solution? Must I commit some cardinal sin and create some horribly messed up NAnt script to achieve the correct publish results that VS2010 delivers so nicely?

like image 755
Thirlan Avatar asked Apr 22 '11 00:04

Thirlan


2 Answers

Okay I figured it out after chancing on this blog, http://blogs.msdn.com/b/webdevtools/archive/2009/05/04/web-deployment-web-config-transformation.aspx

In step 4 he shows a command line arg I haven't seen before, /t:TransformWebConfig

Unfortunately, this alone does not solve the problem. It does perform the transform but the transform is found in obj/Release/TransformWebConfig/transformed/Web.config (obj/Release or obj/Debug or obj/YourTranformName).

So to finally get a decent solution this is what I had to do.

<exec program="${exec.msbuild}" failonerror="true">
    <arg value="${path.sourceCode}/ProjectFolder/Project.csproj" />
    <arg value="/p:Configuration=Release" />
    <arg value="/t:ResolveReferences" />
    <arg value="/t:_CopyWebApplication" />
    <arg value="/t:TransformWebConfig" />
    <arg value="/p:OutDir=${path.buildFromProject}/temp/" />
    <arg value="/p:WebProjectOutputDir=${path.buildFromProject}/ProjectBuild/" />
</exec>

<delete dir="${path.build}/temp" failonerror="true"/>
<delete file="${path.build}/ProjectBuild/Web.config" failonerror="true"/>
<delete file="${path.build}/ProjectBuild/Web.Debug.config" failonerror="true"/>
<delete file="${path.build}/ProjectBuild/Web.Release.config" failonerror="true"/>
<copy file="${path.sourceCode}/ProjectFolder/obj/Release/TransformWebConfig/transformed/Web.config" tofile="${path.build}/ProjectBuild/Web.config" />

Notice that the OutDir is not the same as the WebProjectOutputDir. This is the reason why:

  • OutDir gives you everything in the project "solution".
  • WebProjectOutputDir gives you the bare minimum for the web "project" (i.e. not the entire solution).

A lot of extra baggage was coming over from other projects in the solution using OutDir that we didn't want so we just sent OutDir to a temp folder and deleted as you can see in the steps above. OutDir is absolutely required by the way. The build will not work if you remove it. Seems that WebProjectOutputDir works off of OutDir.

There is only one minor flaw with this entire setup. A lot of pdb files are missing from the bin library. The only pdb copied over was the one from the Web project.

If anyone ever finds a one step solution with MSBuild to this please post it : P Although this is a good solution it is still only 99.9999% perfect and much like the ones listed above I'm sure there's going to be some little nuance or step missed.

like image 185
Thirlan Avatar answered Nov 11 '22 17:11

Thirlan


After checking out your solution I stumbled across another solution https://stackoverflow.com/a/2953376/662853

I revised your answer to use the _WPPCopyWebApplication target instead:

<exec program="${exec.msbuild}" failonerror="true">
    <arg value="${path.sourceCode}/ProjectFolder/Project.csproj" />
    <arg value="/p:Configuration=Release" />
    <arg value="/t:ResolveReferences" />
    <arg value="/t:_WPPCopyWebApplication" />
    <arg value="/t:TransformWebConfig" />
    <arg value="/p:OutDir=${path.buildFromProject}/temp/" />
    <arg value="/p:WebProjectOutputDir=${path.buildFromProject}/ProjectBuild/" />
</exec>

After testing I no longer needed to delete the configs and copy the transformed files.

like image 3
jschay Avatar answered Nov 11 '22 18:11

jschay