Automate ASP.NET Web Application Deployment (MVC) and Subversion

We are trying to automate the build process on our intermediate servers, but at the same time we got confused, albeit rather insignificant. We use the publishing function that is built into VS2010, which switches to Subversion, and then a third-party application (Beanstalk) automatically pulls the updated files and FTP files to the intermediate server.

The problem we are facing is that we have only the following options:

  • (Less than 2 evil). If we decide to use Replace Compliance Files with Local Copies, this works fine, with one exception: this option does not delete files deleted from the project. This will lead to unwanted and / or security problems for unkempt files from the old days.
  • If we decide to use “Delete all existing files before publishing”, this will delete the entire folder structure, including the hidden .SVN folders that Subversion uses to track updates, etc. This seems like the best solution in terms of accuracy, but it really destroys the local SVN environment, which is the average person for this automation.

My question is: is there an easy work for this or a completely different deployment option that we ignore (we don’t want to publish directly to the server from VS, since we want to track who / what / deployment)? The only thing I came across was to delete the contents of the file manually before publishing, leaving the folder structure intact, and then expanding it using "Replace the corresponding files with local copies." Unfortunately, this lends a whole new meaning to the word “automation”.

Any ideas on how best to do this?

+7
source share
4 answers

You might want to use NAnt or something similar for tasks that you want to automate, such as creating and publishing to Subversion. This is a large part of my build file for the WebApplication project. It could be different for MVC. If so, I'm sure you can use this as a starting point. I'm by no means an NAnt expert, so there may be some flaws, but it definitely works for me.

I had to add a PublishToFileSystem target to every .csproj file I wanted to publish. The source of this may be here .

Assembly file also available in Pastebin

<?xml version="1.0"?> <project name="deploy" default="all"> <property name="nant.settings.currentframework" value="net-4.0" /> <!-- Any of these can be passed through the command line --> <property name="sourceDirectory" value="${project::get-base-directory()}" /> <property name="publishDirectory" value="${sourceDirectory}\build" /> <property name="MSBuildPath" value="${framework::get-assembly-directory(framework::get-target-framework())}\msbuild.exe" /> <!-- The build configuration to use when publishing and transforming the web.config file. This is useful when you have multiple environments for which you create builds --> <property name="buildConfiguration" value="Release" /> <!-- Set these as needed --> <property name="svn.username" value="" /> <property name="svn.password" value="" /> <target name="SvnPrep"> <property name="svn.dir" value="${publishDirectory}\.svn" /> <property name="svn.update" value="true" readonly="false" /> <echo>env.svn.path = svn</echo> <echo>svn.dir = ${svn.dir}</echo> <mkdir dir="${publishDirectory}" unless="${directory::exists(publishDirectory)}" /> <!-- Check if there a .svn dir already. If not: checkout, else: update. --> <if test="${not directory::exists(svn.dir)}"> <exec program='svn.exe' workingdir="${publishDirectory}" verbose="true"> <arg line='co ${svn.builduri} --username ${svn.username} --password ${svn.password} --non-interactive ./' /> </exec> <property name="svn.update" value="false" readonly="false" /> </if> <if test="${svn.update}"> <exec program='svn.exe' workingdir="${publishDirectory}\" verbose="true"> <arg line='up --username ${svn.username} --password ${svn.password} --non-interactive --force ./' /> </exec> </if> <!-- Force any conflicts to be resolved with the most recent code --> <exec program='svn.exe' workingdir="${publishDirectory}\" verbose="true"> <arg line='resolve --accept theirs-full -R ./' /> </exec> </target> <target name="DeleteFiles"> <!-- Delete only the files (retain directory structure) in the directory to which you are going to publish/build. NAnt excludes svn directories by default. --> <delete includeemptydirs="false"> <fileset basedir="${publishDirectory}"> <include name="**/*.*" /> </fileset> </delete> </target> <target name="Publish"> <!-- I know there an MSBuild task, I don't know why I didn't use it, but this works. --> <!-- Build and publish frontend --> <exec program="${MSBuildPath}"> <arg line='"${sourceDirectory}\YourProject.csproj"' /> <arg value='"/p:Platform=AnyCPU;Configuration=${buildConfiguration};PublishDestination=${publishDirectory}"' /> <arg value="/target:PublishToFileSystem" /> </exec> <!-- Transform the correct web.config and copy it to the build folder. PublishToFileSystem doesn't transform the web.config, unfortunately. --> <exec program="${MSBuildPath}"> <arg line='"${sourceDirectory}\YourProject.csproj"' /> <arg value='"/p:Platform=AnyCPU;Configuration=${buildConfiguration};PublishDestination=${publishDirectory}"' /> <arg value="/target:TransformWebConfig" /> </exec> <copy file="${sourceDirectory}\YourProject\obj\${buildConfiguration}\TransformWebConfig\transformed\Web.config" tofile="${publishDirectory}\YourProject\web.config" overwrite="true" /> </target> <target name="SvnCommit"> <!-- add any new files --> <exec program='svn.exe' workingdir="${publishDirectory}" verbose="true"> <arg line='add --force .' /> </exec> <!-- delete any missing files, a modification of this http://stackoverflow.com/questions/1071857/how-do-i-svn-add-all-unversioned-files-to-svn --> <!-- When there nothing to delete it looks like this fails (to NAnt) but it is actually fine, that why failonerror is false --> <exec program='cmd.exe' workingdir="${publishDirectory}\" verbose="true" failonerror="false" commandline='/C for /f "usebackq tokens=2*" %i in (`svn status ^| findstr /r "^\!"`) do svn del "%i %j"' > </exec> <exec program='svn.exe' workingdir="${publishDirectory}" verbose="true"> <arg line='commit -m "Automated commit from build runner"' /> </exec> </target> <target name="ShowProperties"> <script language="C#" prefix="util" > <code> <![CDATA[ public static void ScriptMain(Project project) { foreach (DictionaryEntry entry in project.Properties) { Console.WriteLine("{0}={1}", entry.Key, entry.Value); } } ]]> </code> </script> </target> <target name="all"> <call target="ShowProperties" /> <call target="SvnPrep" /> <call target="DeleteFiles" /> <call target="Publish" /> <call target="SvnCommit" /> </target> </project> 
+4
source

We are also deploying SVN and are facing the same problem. Our solution is to essentially divide the project into “significant” updates - situations where we added and deleted files, and not just fixed small errors and made settings that you can usually handle with xcopy. The Svn circuit is as follows:

 --project ---production ----20100101 ----20100213 [etc, etc] 

The procedure is quite simple - if there are big enough changes, check the assembly of artifacts as necessary.

Another thing you might want to try, especially if you can't easily get your production bits to “switch” branches, would be to use something strange, like powershell, to execute the delete files command, which could filter out * .svn folders.

0
source

I would say, “fortunately”, this brings a whole new meaning to word automation :) What you describe is known as application release automation, also sometimes called Deployment Automation. If you really want to know who did what, what was the result, etc., then you are looking for a product like Nolio ASAP (http://www.noliosoft.com). Please let me know if this helps, because from what you describe, this seems like the perfect combination.

+ Daniel

0
source

Why are you publishing the site in a folder processed by Subversion?

The way I do this is to work directly with files in folders managed by SVN. As soon as I complete something, he pulls the beanstalk into the intermediate zone. Thus, deleted files are always deleted from the repo, and you do not need to worry about it. Everything is always in sync.

If you feel that this puts too many files in the staging area, you can still use scripts and Visual Studio commands to publish the site. But I'm not sure how well Beanstalk integrates with this scenario. I know CC.net and many other options.

0
source

All Articles