6
votes

I have the following setup: ASP.Net MVC .Net 4.0 solution with 5 projects in it, and several solution configurations (Site1-Stage, Site1-Live, Site2-Stage, etc). The reason for this is simple - we deploy same codebase to multiple servers with different config settings.

To manage these configurations, I use the approach described by Troy Hunt in his You're deploying it wrong! TeamCity, Subversion & Web Deploy part 1: Config transforms article. In 2 words - I do NOT have web.config in my SVN repo, instead I have Web.Base.Config, Web.Site1-Stage.Config, etc and XmlTransformation task in project AfterBuild target. During the build, the required web.config is generated based on selected configuration:

 <UsingTask TaskName="TransformXml" AssemblyFile="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v10.0\Web\Microsoft.Web.Publishing.Tasks.dll" />
  <Target Name="AfterBuild">
    <TransformXml Source="Web.Base.config" Transform="Web.$(Configuration).config" Destination="Web.config" StackTrace="true" />
  </Target>

Here comes the problem: when I'm execute MSBuild like this:

msbuild MySolution.sln /P:configuration=Site1-Stage /t:rebuild

all goes well, web.config is properly generated for the Site1-Stage configuration. However, if I run this command:

msbuild MySolution.sln /P:configuration=Site1-Stage /t:rebuild /P:DeployOnBuild=True

I get the following error:

"MySolution.sln" (rebuild target) (1) -> "MySolution\MyWebProj.csproj" (Rebuild target) (3) -> (PreTransformWebConfig target) -> C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v10.5\Web\Microsoft.Web.Publishing.targets(1399,5): error : Copying file Web.config to obj\Site1-Stage\TransformWebConfig\original\Web.config failed. Could not find file 'Web.config'. [MySolution\MyWebProj.csproj]

I tried to explicitly add "AfterBuild" target into MSBuild command line:

msbuild MySolution.sln /P:configuration=Site1-Stage /t:rebuild,AfterBuild /P:DeployOnBuild=True

but it resulted in the same error.

Why do I need this: it's a very isolated example, and in reality I'm trying to setup automated publishing from TeamCity CI server. I think if I add new build step with "Visual Studio (sln)" runner BEFORE my current publishing step, that would work, it will first rebuild the project (and generate web.config) - and then publish. However, i have lots of publishing steps (around 20 now) and I would like to avoid that. My understanding is that "Publish" process does the build as part of it, so I would like to "reuse" that.

Question is: how should I modify my MSBuild command line to force config transformation to happen?

Thank you.

1
You AfterBuild target does not have any outputs. It seems that MSBuild skips this target thinking that it is up-to-date. Add outputs (Web.Config in your case) to your AfterBuild target outputs.vharavy
Maybe use "BeforeBuild"? BTW do you have web.config included in csproj? I believe most publish activities relies on items in project rather than in folder - though didn't check it. If not - you can include web.config in project, while still have excluded it from source controlLanorkin
@Lanorkin - that worked! Thanks a lot - please post your comment as an answer.avs099
which one of these two?Lanorkin

1 Answers

4
votes

Maybe use "BeforeBuild"?

BTW do you have web.config included in csproj? I believe most publish activities relies on items in project rather than in folder. You can include web.config in project, while still have excluded it from source control.