Azure pipeline transforming web.config files during release - azure-devops

I'm trying to use web.config transformation in my release pipeline. However, no matter what I'm doing, I always get
2019-11-11T12:19:46.1172474Z ##[warning]Unable to apply transformation for the given package. Verify the following.
I have a Web.config and a Web.Elastic.config. The project has no dependentUpon for any .config files in it's csproj, and Web.Elastic.config has content as build action and is in the zip file generated from the build task.
In addition, I disabled config transformations during building just to be sure. I'm not sure what else I can do. This happens both when using the File Transform Task Preview as well as the XML transformation option during the IIS Web App Deploy task.
The File Transform task is configured like this:
I reduced my configs to this to see if there's something wrong with the transformation itself:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<section name="apiConfig" type="System.Configuration.NameValueSectionHandler, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
</configSections>
<apiConfig>
<add key="ClientBasetUrl" value="http://localhost:4200" />
</apiConfig>
<system.web>
<compilation debug="true" targetFramework="4.6.2">
<assemblies>
<add assembly="System.Net.Http.WebRequest, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
</assemblies>
</compilation>
<!-- This will handle requests up to 20MB -->
<httpRuntime targetFramework="4.6.1" maxRequestLength="20480" />
</system.web>
</configuration>
with the transformation looking like this:
<?xml version="1.0" encoding="utf-8"?>
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<apiConfig xdt:Transform="Replace">
<add key="ClientBasetUrl" value="https://elastic.OURPROJECT.com" />
</apiConfig>
<system.web xdt:Transform="Replace">
<customErrors mode="Off" />
<compilation debug="true" targetFramework="4.6.2" />
<httpRuntime targetFramework="4.6.1" maxRequestLength="20480" />
</system.web>
</configuration>
With System.Debug set to true, the File Transformation task provides the following logs, which are not very helpful:
2019-11-11T12:19:43.1224281Z ##[debug]agent.TempDirectory=C:\vstsagent\A1\_work\_temp
2019-11-11T12:19:43.1289319Z ##[debug]loading inputs and endpoints
2019-11-11T12:19:43.1292645Z ##[debug]loading ENDPOINT_AUTH_PARAMETER_SYSTEMVSSCONNECTION_ACCESSTOKEN
2019-11-11T12:19:43.1301246Z ##[debug]loading ENDPOINT_AUTH_SCHEME_SYSTEMVSSCONNECTION
2019-11-11T12:19:43.1304962Z ##[debug]loading ENDPOINT_AUTH_SYSTEMVSSCONNECTION
2019-11-11T12:19:43.1307442Z ##[debug]loading INPUT_ENABLEXMLTRANSFORM
2019-11-11T12:19:43.1309334Z ##[debug]loading INPUT_FILETYPE
2019-11-11T12:19:43.1316311Z ##[debug]loading INPUT_FOLDERPATH
2019-11-11T12:19:43.1316632Z ##[debug]loading INPUT_XMLTRANSFORMATIONRULES
2019-11-11T12:19:43.1322390Z ##[debug]loaded 7
2019-11-11T12:19:43.1334690Z ##[debug]Agent.ProxyUrl=undefined
2019-11-11T12:19:43.1336439Z ##[debug]Agent.CAInfo=undefined
2019-11-11T12:19:43.1336699Z ##[debug]Agent.ClientCert=undefined
2019-11-11T12:19:43.1336884Z ##[debug]Agent.SkipCertValidation=undefined
2019-11-11T12:19:43.2867243Z ##[debug]check path : C:\vstsagent\A1\_work\_tasks\FileTransform_8ce97e91-56cc-4743-bfab-9a9315be5f27\1.1.6\task.json
2019-11-11T12:19:43.2867893Z ##[debug]adding resource file: C:\vstsagent\A1\_work\_tasks\FileTransform_8ce97e91-56cc-4743-bfab-9a9315be5f27\1.1.6\task.json
2019-11-11T12:19:43.2868317Z ##[debug]system.culture=en-US
2019-11-11T12:19:43.2882674Z ##[debug]check path : C:\vstsagent\A1\_work\_tasks\FileTransform_8ce97e91-56cc-4743-bfab-9a9315be5f27\1.1.6\node_modules\webdeployment-common-v2\module.json
2019-11-11T12:19:43.2883957Z ##[debug]adding resource file: C:\vstsagent\A1\_work\_tasks\FileTransform_8ce97e91-56cc-4743-bfab-9a9315be5f27\1.1.6\node_modules\webdeployment-common-v2\module.json
2019-11-11T12:19:43.2884521Z ##[debug]system.culture=en-US
2019-11-11T12:19:43.2900694Z ##[debug]folderPath=C:\vstsagent\A1\_work\r2\a\SLX-Backend\drop\OURPROJECT.zip
2019-11-11T12:19:43.2902832Z ##[debug]Finding files matching input: C:\vstsagent\A1\_work\r2\a\SLX-Backend\drop\OURPROJECT.zip
2019-11-11T12:19:43.2907625Z ##[debug]fileType=xml
2019-11-11T12:19:43.2908713Z ##[debug]targetFiles=null
2019-11-11T12:19:43.2911002Z ##[debug]enableXmlTransform=true
2019-11-11T12:19:43.2912768Z ##[debug]xmlTransformationRules=-transform **\OURPROJECT\obj\Release\Package\PackageTmp\Web.Elastic.config -xml **\OURPROJECT\obj\Release\Package\PackageTmp\Web.config
2019-11-11T12:19:43.2916829Z ##[debug]This is zip package
2019-11-11T12:19:43.2919443Z ##[debug]Agent.TempDirectory=C:\vstsagent\A1\_work\_temp
2019-11-11T12:19:43.2919672Z ##[debug]Agent.TempDirectory=C:\vstsagent\A1\_work\_temp
2019-11-11T12:19:43.2927405Z ##[debug]extracting C:\vstsagent\A1\_work\r2\a\SLX-Backend\drop\OURPROJECT.zip to C:\vstsagent\A1\_work\_temp\temp_web_package_9699193652416063
2019-11-11T12:19:45.9624316Z ##[debug]extracted C:\vstsagent\A1\_work\r2\a\SLX-Backend\drop\OURPROJECT.zip to C:\vstsagent\A1\_work\_temp\temp_web_package_9699193652416063 Successfully
2019-11-11T12:19:46.0225418Z ##[debug]defaultRoot: 'C:\vstsagent\A1\_work\_temp\temp_web_package_9699193652416063'
2019-11-11T12:19:46.0225668Z ##[debug]findOptions.allowBrokenSymbolicLinks: 'false'
2019-11-11T12:19:46.0225791Z ##[debug]findOptions.followSpecifiedSymbolicLink: 'true'
2019-11-11T12:19:46.0225928Z ##[debug]findOptions.followSymbolicLinks: 'true'
2019-11-11T12:19:46.0226038Z ##[debug]matchOptions.debug: 'false'
2019-11-11T12:19:46.0226147Z ##[debug]matchOptions.nobrace: 'true'
2019-11-11T12:19:46.0226280Z ##[debug]matchOptions.noglobstar: 'false'
2019-11-11T12:19:46.0226387Z ##[debug]matchOptions.dot: 'true'
2019-11-11T12:19:46.0226547Z ##[debug]matchOptions.noext: 'false'
2019-11-11T12:19:46.0226657Z ##[debug]matchOptions.nocase: 'true'
2019-11-11T12:19:46.0226763Z ##[debug]matchOptions.nonull: 'false'
2019-11-11T12:19:46.0226896Z ##[debug]matchOptions.matchBase: 'false'
2019-11-11T12:19:46.0227016Z ##[debug]matchOptions.nocomment: 'false'
2019-11-11T12:19:46.0227146Z ##[debug]matchOptions.nonegate: 'false'
2019-11-11T12:19:46.0227252Z ##[debug]matchOptions.flipNegate: 'false'
2019-11-11T12:19:46.0227392Z ##[debug]pattern: '**\OURPROJECT\obj\Release\Package\PackageTmp\Web.config'
2019-11-11T12:19:46.0227519Z ##[debug]findPath: 'C:\vstsagent\A1\_work\_temp\temp_web_package_9699193652416063'
2019-11-11T12:19:46.0227632Z ##[debug]statOnly: 'false'
2019-11-11T12:19:46.0227769Z ##[debug]findPath: 'C:\vstsagent\A1\_work\_temp\temp_web_package_9699193652416063'
2019-11-11T12:19:46.0227885Z ##[debug]findOptions.allowBrokenSymbolicLinks: 'false'
2019-11-11T12:19:46.0228032Z ##[debug]findOptions.followSpecifiedSymbolicLink: 'true'
2019-11-11T12:19:46.0228152Z ##[debug]findOptions.followSymbolicLinks: 'true'
...
2019-11-11T12:19:46.0970036Z ##[debug]615 results
2019-11-11T12:19:46.0970193Z ##[debug]found 615 paths
2019-11-11T12:19:46.0970374Z ##[debug]applying include pattern
2019-11-11T12:19:46.0970559Z ##[debug]adjustedPattern: 'C:\vstsagent\A1\_work\_temp\temp_web_package_9699193652416063\**\PackageTmp\Web.config'
2019-11-11T12:19:46.1099930Z ##[debug]1 matches
2019-11-11T12:19:46.1100207Z ##[debug]1 final results
2019-11-11T12:19:46.1172474Z ##[warning]Unable to apply transformation for the given package. Verify the following.
2019-11-11T12:19:46.1179673Z ##[debug]Processed: ##vso[task.issue type=warning;]Unable to apply transformation for the given package. Verify the following.

As the configuration in the config files you shared above, there's no any problem in it when apply it on my side.
In fact, in your build log, it has been show you the problem caused by what.
You can see that the task only found out only one file while here it should match 2 files, like this:
These 2 files, one is config and another is transformation config file. But in your build, it can only found out one file (Not sure whether the log you shared is completed, as I see, it only detect out Web.config file).
This issue should relevant the configuration of your task. Seems you were linking the artifact, and want to applying the transformation into that.
Please modify the Package or folder blank as this pic shown:
And change your Transformation rules as:
-transform **\*.Elastic.config -xml **\*.config

Related

Azure Devops release - File Transform - Provided node is empty or a comment

I am trying to transform a .config file from an XML transform file in a release stage. I am using the standard File Transform task. I added a transform.xml file (which isnt linked to a legitimate release) to my artifact and can see it. When i try and use it I get the following System.Debug output:
2020-05-01T17:25:21.6011428Z Processing substitution for xml node : connectionStrings
2020-05-01T17:25:21.6022113Z ##[debug]Provided node is empty or a comment.
2020-05-01T17:25:21.6025339Z ##[debug]Provided node is empty or a comment.
2020-05-01T17:25:21.6027416Z ##[debug]Unable to find node with tag 'configSections' in provided xml file.
2020-05-01T17:25:21.6028615Z Skipped Updating file: xxxxxxxx.config
The contents of the transform.xml file are as below:
<?xml version="1.0" encoding="utf-8" ?>
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<connectionStrings xdt:Transform="Replace">
<add name="XX" connectionString="user id=XXX;password=XXXXX;data source=XXXXXXXX"/>
</connectionStrings>
</configuration>
Azure Devops release - File Transform - Provided node is empty or a comment
I could not reproduce this issue with following configuration file and your transform file:
Configuration file web.config (code sample from XML transformation example):
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<connectionStrings>
<add name="DefaultConnection"
connectionString="Data Source=(LocalDb)\\MSDB;DbFilename=aspcore-local.mdf;" />
</connectionStrings>
<appSettings>
<add key="webpages:Version" value="3.0.0.0" />
<add key="webpages:Enabled" value="false" />
</appSettings>
<system.web>
<authentication mode="None" />
<compilation targetFramework="4.5" debug="true" />
</system.web>
</configuration>
Then create a Web.test.config with your contents of the transform file:
<?xml version="1.0" encoding="utf-8" ?>
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<connectionStrings xdt:Transform="Replace">
<add name="XX" connectionString="user id=XXX;password=XXXXX;data source=XXXXXXXX"/>
</connectionStrings>
</configuration>
Note:
XML transformation will be run on the *.config file for transformation configuration files named *.Release.config or *.<stage>.config. So, we could not use the transform.xml instead of *.<stage>.config.
As the test result, the connectionStrings string in the web.config was replaced:
Please check the document File transforms and variable substitution reference for some more details.
Hope this helps.

XDT Transform not working for applicationHost.xdt on Azure - Environment variables are ignored

It seems like environment variables are being ignored in my xdt transform for applicationHost.
I've created the following file applicationHost.xdt on azure in the \home\site folder. It does NOT perform the transform on applicationHost.config
<?xml version="1.0"?>
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">>
<system.applicationHost>
<applicationPools>
<add name="%WEBSITE_SITE_NAME%" xdt:Locator="Match(name)">
<recycling disallowOverlappingRotation="true" xdt:Transform="Insert" />
</add>
<add name="%WEBSITE_IIS_SITE_NAME%" xdt:Locator="Match(name)">
<recycling disallowOverlappingRotation="true" xdt:Transform="Insert" />
</add>
</applicationPools>
</system.applicationHost>
</configuration>
If I adjust the %WEBSITE_SITE_NAME% to say "dev-mysitename.com" the transforms work properly.
Why are the Environment variables not working properly? I need this to work so my different environments will work properly.
You cannot use Environment Variables like this. Its just not possible.

Update Build number in App config xml file on build pipeline

I have a build pipeline in Azure DevOps, I need to update the build number in my apconfig exe file that will be $(Build.BuildNumber).
I just tried this way:
Adding a variable name = BuildNumber value = $(Build.BuildNumber).
And in my apconfig.exe file have a key same like <add key="BuildNumber" value="1812201901" />.
Why I have tried like this way: thinking like it will update in the config file if variable name match with the key.
But it is not working. can anyone please help? I have just started in CI/CD.
Update Build number in App config xml file on build pipeline
Just like the Shayki said, using the Replace Tokens extension should be the directly way to resolve this issue.
But since you need to request to get this extension, as workaround, you could also use power shell scripts to resolve this issue, you can check below my test powershell scripts:
$currentDirectory = [IO.Path]::GetDirectoryName($MyInvocation.MyCommand.Path)
$appConfigFile = [IO.Path]::Combine($currentDirectory, 'App.config')
$appConfig = New-Object XML
$appConfig.Load($appConfigFile)
foreach($BuildNumber in $appConfig.configuration.add)
{
'name: ' + $BuildNumber.name
'BuildNumber: ' + $BuildNumber.value
$BuildNumber.value = '123456789'
}
$appConfig.Save($appConfigFile)
As result, the app.config:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<add key="BuildNumber" value="123456789" />
</configuration>
Note: Set the powershell scripts at the same folder of the app.config file.
Hope this helps.
You can use the Replace Tokens extension and in the apconfig.exe file put this:
<add key="BuildNumber" value="__BuildNumber__" />
Configure the task to search variables with __ prefix and suffix:
Now the value will be replaced with the value of the BuildNumber variable you configured (equal to Build.BuildNumber).

Modify a .Net Applications .exe.config file Settings Value via Powershell

I have a .Net console application which has an App.Config / MyApplicationConsole.exe.config file. This one contains settings set via the properties manager of VS, basically looking something like this:
<?xml version="1.0"?>
<configuration>
<configSections>
<sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<section name="My.Applications.Namespace.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</sectionGroup>
</configSections>
<applicationSettings>
<My.Applications.Namespace.Properties.Settings>
<setting name="SettingsKeyABC" serializeAs="String">
<value>SomeOtherValue</value>
</setting>
<setting name="SettingsKeyXYZ" serializeAs="String">
<value>True</value>
</setting>
</Siemens.Med.CTE.PMP.Applications.JobExecutor.Properties.Settings>
</applicationSettings>
<system.diagnostics>
<trace>
<listeners>
<add name="Gibraltar" type="Gibraltar.Agent.LogListener, Gibraltar.Agent" />
</listeners>
</trace>
</system.diagnostics>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0" />
</startup>
</configuration>
Now what I want/need to do is modify the ("True") value for the "SettingsKeyXYZ" setting, preferably via powershell (as my colleague set up). Does anyone know how to do this? All I found were sample for Web.Configs which seem a tad different than the ones created by VS.
First, The xml text is not valid. Where's the closing tag of line 10 tag (My.Applications.Namespace.Properties.Settings). I changed line 10 to match the closing tag.
Load the file (as xml), you must put the 'My.Applications.Namespace.Properties.Settings' tag in quotes otherwise powershell will try to parse each value between the dots as a tag), update the value to False and then save the file.
[xml]$xml = Get-Content c:\App.Config
$xml.configuration.applicationSettings.'My.Applications.Namespace.Properties.Settings'.setting.value='False'
$xml.Save('c:\App.Config')

How can I force IIS 7 to flush output?

In IIS 6, using Perl, I was able to send a stream of output to the client rather than buffering the entire thing and dumping it out at all once. This allowed such things as progress bars and such to be used.
How can I accomplish the same thing in IIS 7?
Under IIS 7, once you have created the Perl Script script mapping, you can add an attribute that will fix this.
You modify the %windir%\system32\inetsrv\config\applicationHost.control file and find the script mapping by name (in my case, Perl-Script). Then add the responseBufferLimit attribute into the XML, for example:
<add name="Perl-Script" path="*.pl" blah blah blah responseBufferLimit="0" />
This causes IIS to run as it did in IIS 6, with buffering off.
You can customize the web application's web.config to set responseBufferLimit="0" instead of changing global settings. Example web.config:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<handlers>
<add name="Perl CGI for .pl (custom)" path="*.pl" verb="GET,HEAD,POST" modules="CgiModule" scriptProcessor="C:\Perl64\bin\perl.exe "%s" %s" resourceType="File" requireAccess="Script" responseBufferLimit="0" />
</handlers>
</system.webServer>
<system.web>
<identity impersonate="false" />
</system.web>
</configuration>
Place this file in the web root directory. It will override server settings for *.pl.
The ONLY thing that worked for my in IIS 7.5 (Windows 7) was the following command, run from CMD:
appcmd.exe set config /section:handlers "/[name='PHP_via_FastCGI'].ResponseBufferLimit:0"
NOTE: You must replace PHP_via_FastCGI with the name of your PHP handler in "Handler Mappings".