Welcome to the navigation

Duis do consectetur nisi aliquip culpa irure est ut eu nostrud cupidatat nulla fugiat non officia et aute velit dolore sunt ut laboris magna ad. Eu ipsum sit voluptate dolore dolore est duis laboris anim non consequat, fugiat ex excepteur occaecat ut in pariatur, lorem exercitation ea laborum, dolor do

Yeah, this will be replaced... But please enjoy the search!

Web.config transforms not working in Azure DevOps Pipeline

This is a problem with many dimensions and can be caused by different misconfigurations. In this blog post, I will walk through the most common errors and how to fix them.

Some words of my setup for this post

I'm deploying an ASP.NET Framework web application to an Azure App Service using Azure DevOps Build and Release pipeline. The Azure App Service environments are named Test and Production and have corresponding transform files, i.e. Web.Test.Config and Web.Production.Config

The build and release works but environment-specific settings aren't transformed

Most likely there is an error saying 

##[warning]Unable to apply transformation for the given package. Verify the following.
##[warning]1. Whether the Transformation is already applied for the MSBuild generated package during build. If yes, remove the  tag for each config in the csproj file and rebuild. 
##[warning]2. Ensure that the config file and transformation files are present in the same folder inside the package.

Check your warnings in the log, Azure DevOps > Project > Pipelines > Releases > The actual Pipeline

If my assumption is correct this would mean that there are no config files to transform since the msbuild process may have run the transforms and thus also removed the transform config files, this can be confirmed by downloading the artefact from the build step.

Below we can see that there are files left to transform when sent to the release pipeline

Suggestions sais that removing DependentUpon for the transform files from the csproj-file would solve this. I.e making this 

<None Include="Web.Debug.config">
	<DependentUpon>Web.config</DependentUpon>
</None>
<None Include="Web.Release.config">
	<DependentUpon>Web.config</DependentUpon>
</None>
<Content Include="Web.Test.config">
	<DependentUpon>Web.config</DependentUpon>
</Content>
<Content Include="Web.Production.config">
	<DependentUpon>Web.config</DependentUpon>
</Content>

looking like this

<None Include="Web.Debug.config">
	<DependentUpon>Web.config</DependentUpon>
</None>
<None Include="Web.Release.config">
	<DependentUpon>Web.config</DependentUpon>
</None>
<None Include="Web.Test.config" />
<None Include="Web.Production.config" />

also adding some parameters to the MSBuild process step, in my case I'll edit the yaml file

/p:MarkWebConfigAssistFilesAsExclude=false 
/p:ProfileTransformWebConfigEnabled=false 
/p:TransformWebConfigEnabled=false 
/p:AutoParameterizationWebConfigConnectionStrings=false

None of the above worked for me, the MSBuild step still removed all the transform files and the error was the same. It does, however, seem to have worked for some pipelines

My solution

Verify that the transform files I want to are actually passed to the release pipeline. That would make my csproj-file look like this 

<None Include="Web.Debug.config">
	<DependentUpon>Web.config</DependentUpon>
</None>
<None Include="Web.Release.config">
	<DependentUpon>Web.config</DependentUpon>
</None>
<Content Include="Web.Test.config">
	<DependentUpon>Web.config</DependentUpon>
</Content>
<Content Include="Web.Production.config">
	<DependentUpon>Web.config</DependentUpon>
</Content>

That this means is that files flagged with none will not be included in the artefact but can still be used by MSBuild and files flagged with Content is seen as content and will always be included in the artefact (almost, please continue to read), config files flagged with content can also be used by MSBuild if need be. Since I'm only interested in doing some environment post-processing on the config files this is fine, I have no need for Debug or Release-configuration files.

Config files are somewhat special in the .net world and we will still need to tell MSBuild to put config files flagged included as Content in the artefact. Add the following to your MSBuild parameters 

/p:MarkWebConfigAssistFilesAsExclude=false /p:TransformWebConfigEnabled=false 

Above is the minimal configuration you will need to use to have this working, unfortunately, MSBuild and the Release pipelines does not allow you to run multiple transforms in one pipeline.

Verifying my artefact

At this point, the release pipeline should work as expected. Don't forget to ensure that transforms are enabled in the release pipeline! And if the artefact includes the Debug or Release transform file it is most likely to fail during the transformation process.