The web.config transform appears at first glance to be somewhat orphaned in Azure DevOps. If you are deploying to a WebApp then the pipeline wizard will probably have given you this snippet for your Build step:
- task: VSBuild@1
inputs:
solution: '$(solution)'
msbuildArgs: '/p:DeployOnBuild=true /p:WebPublishMethod=Package /p:PackageAsSingleFile=true /p:SkipInvalidConfigurations=true /p:DesktopBuildPackageLocation="$(build.artifactStagingDirectory)\WebApp.zip" /p:DeployIisAppPath="Default Web Site"'
platform: '$(buildPlatform)'
configuration: '$(buildConfiguration)'
To run config transforms you can add the additional parameter /p:TransformConfigFile=true to your msbuildArgs.
The replacement, of course, is the independent FileTransform task (which can also work within zip files). But once your site is packaged the Web.Release.Config is left behind; so you have to run the FileTransform task before, not after, the build step. (Similarly the WebAppDeployment task can't transform a Web.Release.config that isn't inside the package).
Slightly magically, the default parameter for the FileTransform is exactly what you typically want for web.Release.config transforms:
#xmlTransformationRules: '-transform **\*.Release.config -xml **\*.config-transform **\*.$(Release.EnvironmentName).config -xml **\*.config' # Optional
FileTransform can also do variable substitution, and you can have multiple FileTransform steps in your pipeline. I also like to see some diagnostic feedback so I include script step to show the xml transform result. But I put it before variable substitution, because the variables often include secrets:
- task: FileTransform@1
displayName: Transform Release.Config
inputs:
folderPath: '$(System.DefaultWorkingDirectory)/Ui/'
enableXmlTransform: true
xmlTransformationRules: -transform **/*.Release.config -xml **/*.config
- task: PowerShell@2
displayName: "Confirm web.config transform"
inputs:
targetType: 'inline'
script: 'cat $env:System_DefaultWorkingDirectory/Ui/web.config'
errorActionPreference: 'continue'
- task: FileTransform@1
displayName: Variable substitution *.config
inputs:
folderPath: '$(System.DefaultWorkingDirectory)/Ui/'
fileType: 'xml'
targetFiles: '**/*.config'
- task: VSBuild@1
...etc..
Reference
Thanks for the post.
Had a quick question …
I am performing same transform via classic editor due to on-prem ads, the issue i am running into is .. variable substitution doesn’t work if xml transformation is enabled, but will work only when Only variable substitution is enabled. Is that possible. I want to use both the options. Like i want to transform the existing config file and substitute the remaining values. that would have less involvement from other teams. Am i missing something …
Here’s our dilemma with “when” to do a config transform: We do a build of our “master” branch, and deploy it to staging with the “Staging” transform applied. How do we then promote it to production without doing a rebuild/re-transform with “Release” applied to the web.config?
The Azure DevOps release pipeline allows for the use of the File Transform Task, so we were thinking we could apply the desired transform at release time rather than build time. That way we are releasing the exact same build that we tested in staging–we are just changing the config. But… that requires the config transform files be available at release time. Separate set of Artifacts? Or include them in the build output and delete them at release time? Seems like an awkward fit.