2

I am using the FileTransform@2 task to transform a web.config with a web.[environment].config in a Azure DevOps Pipeline (yaml). It seems to fail on one of the individual transforms which fails the whole job, though I'm not sure why.

Here is the error message from the task:

Executing SetAttributes (transform line 72, 48)
on /configuration/appSettings/add[@key='PCWSUser']
System.NullReferenceException: Object reference not set to an instance of an object.
Applying to 'add' element (no source line info)
   at Microsoft.Web.XmlTransform.XmlTransformationLogger.ConvertUriToFileName(XmlDocument xmlDocument)
Set 'key' attribute
   at Microsoft.Web.XmlTransform.XmlTransformationLogger.LogWarning(XmlNode referenceNode, String message, Object[] messageArgs)
Set 'value' attribute
   at Microsoft.Web.XmlTransform.Transform.ApplyOnAllTargetNodes()
Set 2 attributes
Done executing SetAttributes

So it looks like it doesn't like the PCWSUser appSetting.

Here's the web.config snippet for PCWSUser:

...
<add key="PCWSUser" value="TheUserName" />
...

Here's the web.[environment].config (in this case web.qa.config) snippet for PCWSUser:

...
<add key="PCWSUser" value="TheUserNameQA" xdt:Transform="SetAttributes" xdt:Locator="Match(key)"/>
...

I'm not really sure what I'm doing wrong... When the transform is done locally in Visual Studio it doesn't have any problem with it. Another strange thing is I've ran this a few times and it seems to pick a different appSetting to error out on each time. Same error message and all, just different settings. All the settings are set up this way FYI.

Let me know if you need any more info.

EDIT 1

As per @Kevin Lu-MSFT suggestion, I added /p:TransformWebConfigEnabled=false to the build step and tried again.

Build stage logs:

##[debug]INPUT_MSBUILDARGS: '/t:rebuild /p:DeployOnBuild=true /p:PublishProfile="Dev" /p:PackageLocation="D:\agent\_work\283\a" /p:TransformWebConfigEnabled=false'

However, the transform still failed, although the error moved around again. This time the error is in between 2 steps so Im not even clear what went wrong.

Deploy stage logs:

Executing Replace (transform line 10, 105)
on /configuration/connectionStrings/add[@name='SqlConnectionString']
Applying to 'add' element (no source line info)
Replaced 'add' element
Done executing Replace
System.NullReferenceException: Object reference not set to an instance of an object.
   at Microsoft.Web.XmlTransform.XmlTransformationLogger.ConvertUriToFileName(XmlDocument xmlDocument)
   at Microsoft.Web.XmlTransform.XmlTransformationLogger.LogWarning(XmlNode referenceNode, String message, Object[] messageArgs)
   at Microsoft.Web.XmlTransform.Transform.ApplyOnAllTargetNodes()
Executing Replace (transform line 11, 105)
on /configuration/connectionStrings/add[@name='DB2ConnectionString']
Applying to 'add' element (no source line info)
Replaced 'add' element
Done executing Replace
Hershizer33
  • 1,206
  • 2
  • 23
  • 46
  • Do you have the values as pipeline variables? – Crowcoder Jul 09 '20 at 22:40
  • You could refer to the troubleshooting steps in the answer. You can try to run the task directly in the pipeline to convert the file. If it doesn't help, you may share the build definition with us. – Kevin Lu-MSFT Jul 10 '20 at 06:31
  • @Crowcoder Its a mix. I have actual separate files (web.config and web.qa.config in this case), but the connection strings come from Keyvault via substitution. The substitution seems fine. The Keyvault task injects them into the pipeline as variables. – Hershizer33 Jul 10 '20 at 14:44

1 Answers1

1

Based on my test, the FileTransform task could transform the web.config file successfully.

Here are the steps (directly transform the file without build the project), you could refer to them.

Step1: File structure. You need to make sure that the files are in the same folder.

Files

Web.config

<configuration>
  <connectionStrings>

  <appSettings>
....
    <add key="PCWSUser" value="TheUserName" />
  </appSettings>

</configuration>

web.qa.config

<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
   ....
  <appSettings>
    <add key="PCWSUser" value="TheUserNameQA" xdt:Transform="SetAttributes" xdt:Locator="Match(key)"/>
  </appSettings>

</configuration>

Step2: Use the FileTransform task with Yaml.

  - task: FileTransform@2
      inputs:
        folderPath: 'configfolder'
        xmlTransformationRules: '-transform **\web.qa.config -xml **\web.config'  

Then the task could run successfully. But if the folder contains multiple transform files, it may cause error.

On the other hand, if the FileTransform task is after the build step ,you need to make sure the build task doesn't transform the web.config file.

You could add the Msbuild arguments /p:TransformWebConfigEnabled=false in the build task.

enter image description here

Here is a discussion about this issue.

Hope this helps.

Kevin Lu-MSFT
  • 20,786
  • 3
  • 19
  • 28
  • Kevin, you were right that a transform was also happening at the build stage, so I added your `/p:TransformWebConfigEnabled=false` flag and tried again. It still failed, but with a different error message this time. More details under `Edit 1` on the original question if you don't mind. – Hershizer33 Jul 10 '20 at 14:49
  • Also, the folder does contain multiple config transform files (web.dev.config, web.qa.config, web.shadow.config, and web.prod.config), but I am telling it the specific one in the `xmlTransformationRules` setting. – Hershizer33 Jul 10 '20 at 14:55
  • To narrow down this issue, you could directly use the File Transform task to transform the web.config file (without build step). Please check if it could work. If it could work, this issue still relates with the build step. You may refer to [this ticket](https://stackoverflow.com/questions/57955114/how-to-stop-msbuild-from-transforming-web-config-in-azure-devops-pipelines). – Kevin Lu-MSFT Jul 13 '20 at 07:49
  • Kevin, I did notice that part of the problem is its transforming the wrong web.config (itll throw an error about can't insert connection string because there's no connection strings node) This is because my solution has a few web.configs. How can I ensure its only transforming the main web.config? Here is my transform rule: `'-transform **\Web.$(environment).config -xml **\Web.config'` – Hershizer33 Jul 17 '20 at 13:49
  • You could try to add the `target file` parameters to the task:`targetFiles: web.config`. Please check if it could ensure the correct file. – Kevin Lu-MSFT Jul 20 '20 at 01:13