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?
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:
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With