web.config transformation does not work on build server
Solution 1
We've been using publish targets in our web application projects and had seen that the build process was correctly transforming our web.config files, but when we moved the build to our CI server, the transforms were not being applied.
The MSBuild script were using was:
MSBuild.exe PATH_TO_PROJ.csproj /p:DeployOnBuild=true /p:PublishProfile=PUBLISH_TARGET
What we found was that we still needed to specify the Configuration as Debug or Release (even though this appears to be an attribute of the publish target.)
MSBuild.exe PATH_TO_PROJ.csproj /p:DeployOnBuild=true /p:PublishProfile=PUBLISH_TARGET /p:Configuration=Release
Solution 2
I believe that for config transforms to occur when publishing using MSBuild rather than Visual Studio, you need to add a TransformXml task to your project.
This answer gives a guide on what you need to add, but to save a click:
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" />
<Target Name="BeforeBuild">
<TransformXml Source="Web.config" Transform="Web.$(Configuration).config" Destination="Web.config" />
</Target>
You may need to change the path to the .targets file to be in line with whatever version is installed on your build server.
Solution 3
There are multiple conditions that need to be meet in order to generate transforms correctly
Inside .csproj make sure you have all of the following:
<Project> ...
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v$(VisualStudioVersion)\Web\Microsoft.Web.Publishing.targets" />
<Target Name="SetTransformAppConfigDestination" BeforeTargets="PrepareForBuild" Condition="exists('Web.$(Configuration).config')">
<PropertyGroup>
<!-- Force build process to use the transformed configuration file from now on. -->
<AppConfig>$(IntermediateOutputPath)$(TargetFileName).config</AppConfig>
</PropertyGroup>
<Message Text="AppConfig transformation destination: = $(AppConfig)" />
</Target>
<Target Name="TransformAppConfig" AfterTargets="PrepareForBuild" Condition="exists('Web.$(Configuration).config')">
<TransformXml Source="Web.config" Transform="Web.$(Configuration).config" Destination="$(AppConfig)" />
</Target>
</Project>
Update your item group in .csproj file as well .
<ItemGroup> ...
<Content Include="Web.config">
<SubType>Designer</SubType>
</Content>
<Content Include="Web.Debug.config">
<DependentUpon>Web.config</DependentUpon>
</Content>
<Content Include="Web.Release.config">
<DependentUpon>Web.config</DependentUpon>
<IsTransformFile>True</IsTransformFile>
</Content>
<Content Include="Views\Web.config" />
<Content Include="Views\Home\Index.cshtml" />
</ItemGroup>
This will result in your config file to be nested in explorer view
Then make sure you have your path set correctly in properties -> build
Then add to your web.release.config tags for each node to be transformed
- xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform"
- xdt:Transform="Replace"
to look like this:
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<appSettings xdt:Transform="Replace">
<add key="VariableToBeTransformed" value="ValueToInsert"/>
</appSettings>
<system.web>
<compilation xdt:Transform="RemoveAttributes(debug)" />
</system.web>
</configuration>
Also make sure your Solution configuration matches Debug/Release as intended
Hope this helps everyone, you can do the same for app.config
jack
Updated on July 21, 2022Comments
-
jack almost 2 years
We are setting up continuous integration with team city doing builds on check-ins. This works fine, however it always builds with default web.config, it does not transform with development environment specific web config. In Visual Studio, I have custom build configuration created for development. The
web.development.config
transforms correctly when I publish locally withdevelopment
configuration selected, but this does not happen on the build server. In team city, as part of msbuild step I have created a build parametersys.configuration
and I am passingdevelopment
as the value. But when it runs, the resulting web.config is not transformed with the development settings. I also tried setting the command line parameter to/p:configuration=development
with no success.Any help will be much appreciated.
-
jack about 8 yearsThis worked for me! Thanks for the help. All I did was, unload my project copied the above code to my project file. Note: By default "BeforeBuild" is commented.
-
MichaelMao almost 7 yearsThis solution will change the original web.config so when you try to build the project in VS it would ask you to overwrite the web.config every time. In my opinion it's not acceptable.
-
Kevin Smith about 6 yearsOddly adding
/p:Configuration=Release
worked even though my publish profile is set to that too! Thanks! -
Joe Lau over 5 yearsappending /p:Configuration=MyConfig works for me! Thanks!
-
baur over 2 yearsimproved version:
<TransformXml Source="Web.config" Transform="Web.$(Configuration).config" Destination="Web.config" Condition="Exists('Web.$(Configuration).config') AND '$(BuildingInsideVisualStudio)' != 'true'" />