im trying to make Web.Config transformations work. I have got base Web.config:
... (irrelevant code)
<configuration>
<connectionStrings>
<add name="sampleConnStringName" connectionString="sampleConnString" providerName="System.Data.EntityClient" />
</connectionStrings>
... (irrelevant code)
Then i have Web.Debug.config:
<?xml version="1.0"?>
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<connectionStrings>
<add name="sampleConnStringName" connectionString="debugConnString" providerName="System.Data.EntityClient"
xdt:Transform="SetAttributes" xdt:Locator="Match(name)"/>
</connectionStrings>
</configuration>
and Web.Release.config:
<?xml version="1.0"?>
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<connectionStrings>
<add name="sampleConnStringName" connectionString="releaseConnString" providerName="System.Data.EntityClient"
xdt:Transform="SetAttributes" xdt:Locator="Match(name)"/>
</connectionStrings>
</configuration>
Of course transformation is not working when i'm building my app locally, but unfortunately it's also not working while using Azure YAML pipeline.
Relevant YAML part:
variables:
BuildPlatform: 'any cpu'
BuildConfiguration: 'Release'
... (irrelevant code)
task: VSBuild@1
displayName: Build MyUi
inputs:
solution: "$(solution)"
msbuildArgs: '/p:TransformConfigFile=true /p:DeployDefaultTarget=WebPublish /p:DeployOnBuild=true /p:WebPublishMethod=FileSystem /p:publishUrl="$(build.artifactStagingDirectory)\MyUi" /p:SkipInvalidConfigurations=true /p:PackageLocation="$(build.artifactStagingDirectory)\MyUi"'
platform: "$(buildPlatform)"
configuration: "$(buildConfiguration)"
- task: PublishBuildArtifacts@1
displayName: Publishing MyUi to artifacts
inputs:
PathtoPublish: '$(Build.ArtifactStagingDirectory)\MyUi'
ArtifactName: 'drop'
publishLocation: 'Container'
Even on this step (there are other steps in this pipeline like using VM Azure Agent with multiple CopyFiles@2 tasks), in artficats i can see the web.config being.. totally different - it's not even the original Web.config, it contains connections string mixed from app.config files from other projects in this solution - no matter if i add web.debug.config and web.release.config, and change main web.config, the web.config published to artifacts remains the same.
At first i thought that the web.config might not be even copied, but in properties it's marked as "Copy always" so it's not that case.
Maybe someone had this problem before, and can share solution, or better approach for this problem?
Edit: Azure Pipeline log:
PreTransformWebConfig:
Found The following for Config tranformation:
Web.config, bin\Web.config
Creating directory "D:\a\1\s\2. UIlayer\MyUi\obj\Release\TransformWebConfig\transformed\".
Creating directory "D:\a\1\s\2. UIlayer\MyUi\obj\Release\TransformWebConfig\transformed\bin\".
Copying Web.config to obj\Release\TransformWebConfig\original\Web.config.
Copying D:\a\1\s\2. UIlayer\MyUi\Web.config to obj\Release\TransformWebConfig\original\bin\Web.config.
Copying D:\a\1\s\2. UIlayer\MyUi\Web.Release.config to obj\Release\TransformWebConfig\assist\Web.config.
Copying D:\a\1\s\2. UIlayer\MyUi\bin\Web.Release.config to obj\Release\TransformWebConfig\assist\bin\Web.config.
TransformWebConfigCore:
Transforming Source File: D:\a\1\s\2. UIlayer\MyUi\Web.config
Applying Transform File: D:\a\1\s\2. UIlayer\MyUi\Web.Release.config
Output File: obj\Release\TransformWebConfig\transformed\Web.config
Transformation succeeded
TransformWebConfigCore:
Transforming Source File: D:\a\1\s\2. UIlayer\MyUi\Web.config
Applying Transform File: D:\a\1\s\2. UIlayer\MyUi\bin\Web.Release.config
Output File: obj\Release\TransformWebConfig\transformed\bin\Web.config
Transformation succeeded
PostTransformWebConfig:
Transformed Web.config using D:\a\1\s\2. UIlayer\MyUi\Web.Release.config into obj\Release\TransformWebConfig\transformed\Web.config.
Transformed D:\a\1\s\2. UIlayer\MyUi\Web.config using D:\a\1\s\2. UIlayer\MyUi\bin\Web.Release.config into obj\Release\TransformWebConfig\transformed\bin\Web.config.
...
Copying obj\Release\TransformWebConfig\transformed\Web.config to obj\Release\Package\PackageTmp\Web.config.
Copying obj\Release\TransformWebConfig\transformed\bin\Web.config to obj\Release\Package\PackageTmp\bin\Web.config.
...
WebFileSystemPublish:
Creating directory "D:\a\1\a\MyUi".
Copying obj\Release\Package\PackageTmp\Web.config to D:\a\1\a\MyUi\Web.config.
AutoParameterizationWebConfigConnectionStringsCore:
Transforming Source File: D:\a\1\s\2. UIlayer\MyUi\obj\Release\Package\PackageTmp\bin\Web.config
Applying Transform File: <?xml version="1.0"?>
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<connectionStrings>
<add
connectionString="{% token='$(ReplacableToken_#(parameter)_#(tokennumber))' xpathlocator='name' parameter='$(name)-Web.config Connection String' description='$(name) Connection String used in web.config by the application to access the database.' defaultValue='$(connectionString)' tags='SqlConnectionString' %}"
xdt:Transform="SetTokenizedAttributes(connectionString)" xdt:SupressWarnings="True" />
</connectionStrings>
</configuration>
Output File: obj\Release\CSAutoParameterize\transformed\bin\Web.config
Transformation succeeded
PostAutoParameterizationWebConfigConnectionStrings:
Auto ConnectionString Transformed obj\Release\Package\PackageTmp\Web.config into obj\Release\CSAutoParameterize\transformed\Web.config.
Auto ConnectionString Transformed obj\Release\Package\PackageTmp\bin\Web.config into obj\Release\CSAutoParameterize\transformed\bin\Web.config.
...
AutoParameterizationWebConfigConnectionStringsCore:
Transforming Source File: D:\a\1\s\2. UIlayer\MyUi\obj\Release\Package\PackageTmp\Web.config
Applying Transform File: <?xml version="1.0"?>
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<connectionStrings>
<add
connectionString="{% token='$(ReplacableToken_#(parameter)_#(tokennumber))' xpathlocator='name' parameter='$(name)-Web.config Connection String' description='$(name) Connection String used in web.config by the application to access the database.' defaultValue='$(connectionString)' tags='SqlConnectionString' %}"
xdt:Transform="SetTokenizedAttributes(connectionString)" xdt:SupressWarnings="True" />
</connectionStrings>
</configuration>
Output File: obj\Release\CSAutoParameterize\transformed\Web.config
Transformation succeeded
Transforming Source File: D:\a\1\s\2. UIlayer\MyUi\obj\Release\Package\PackageTmp\bin\Web.config
Applying Transform File: <?xml version="1.0"?>
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<connectionStrings>
<add
connectionString="{% token='$(ReplacableToken_#(parameter)_#(tokennumber))' xpathlocator='name' parameter='$(name)-Web.config Connection String' description='$(name) Connection String used in web.config by the application to access the database.' defaultValue='$(connectionString)' tags='SqlConnectionString' %}"
xdt:Transform="SetTokenizedAttributes(connectionString)" xdt:SupressWarnings="True" />
</connectionStrings>
</configuration>
Output File: obj\Release\CSAutoParameterize\transformed\bin\Web.config
Transformation succeeded
As per the VSBuild
task log, after the config transform, it has another automatic parameterization of connection strings in the web.config file during the build. Please add /p:AutoParameterizationWebConfigConnectionStrings=False
in msbuildArgs to skip it.
I created an old .net framework MVC app, and the web.config is transfromed by the Web.release.config as expected:
My task below:
- task: VSBuild@1
displayName: Build solution
inputs:
solution: $(BuildParameters.solution)
msbuildArgs: /p:DeployOnBuild=true /p:AutoParameterizationWebConfigConnectionStrings=False /p:WebPublishMethod=FileSystem /p:publishUrl="$(build.artifactStagingDirectory)\MyUi" /p:SkipInvalidConfigurations=true /p:PackageLocation="$(build.artifactStagingDirectory)\MyUi"
platform: $(BuildPlatform)
configuration: $(BuildConfiguration)